Merge pull request #17165 from reitermarkus/docs-private-by-default
This commit is contained in:
commit
e479f4bc35
2
.github/ISSUE_TEMPLATE.md
vendored
2
.github/ISSUE_TEMPLATE.md
vendored
@ -1 +1 @@
|
|||||||
# Please fill out one of the templates on: https://github.com/Homebrew/brew/issues/new/choose or we will close it without comment.
|
Please fill out one of the templates on https://github.com/Homebrew/brew/issues/new/choose or we will close your issue without comment.
|
||||||
|
|||||||
19
.github/workflows/docs.yml
vendored
19
.github/workflows/docs.yml
vendored
@ -25,9 +25,22 @@ jobs:
|
|||||||
- name: Install vale
|
- name: Install vale
|
||||||
run: brew install vale
|
run: brew install vale
|
||||||
|
|
||||||
- name: Run vale for docs linting
|
- name: Lint docs
|
||||||
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}/docs
|
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||||
run: vale .
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Avoid failing on broken symlinks.
|
||||||
|
rm Library/Homebrew/os/mac/pkgconfig/fuse/fuse.pc
|
||||||
|
rm Library/Homebrew/os/mac/pkgconfig/fuse/osxfuse.pc
|
||||||
|
|
||||||
|
# No ignore support (https://github.com/errata-ai/vale/issues/131).
|
||||||
|
rm -r Library/Homebrew/vendor
|
||||||
|
|
||||||
|
vale .
|
||||||
|
|
||||||
|
# Restore removed files.
|
||||||
|
git reset --hard
|
||||||
|
|
||||||
- name: Install Ruby
|
- name: Install Ruby
|
||||||
uses: ruby/setup-ruby@1198b074305f9356bd56dd4b311757cc0dab2f1c # v1.175.1
|
uses: ruby/setup-ruby@1198b074305f9356bd56dd4b311757cc0dab2f1c # v1.175.1
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -107,6 +107,7 @@
|
|||||||
**/vendor/bundle/ruby/*/gems/rainbow-*/
|
**/vendor/bundle/ruby/*/gems/rainbow-*/
|
||||||
**/vendor/bundle/ruby/*/gems/rbi-*/
|
**/vendor/bundle/ruby/*/gems/rbi-*/
|
||||||
**/vendor/bundle/ruby/*/gems/rdoc-*/
|
**/vendor/bundle/ruby/*/gems/rdoc-*/
|
||||||
|
**/vendor/bundle/ruby/*/gems/redcarpet-*/
|
||||||
**/vendor/bundle/ruby/*/gems/regexp_parser-*/
|
**/vendor/bundle/ruby/*/gems/regexp_parser-*/
|
||||||
**/vendor/bundle/ruby/*/gems/rexml-*/
|
**/vendor/bundle/ruby/*/gems/rexml-*/
|
||||||
**/vendor/bundle/ruby/*/gems/rspec-*/
|
**/vendor/bundle/ruby/*/gems/rspec-*/
|
||||||
|
|||||||
@ -1,4 +1,7 @@
|
|||||||
StylesPath = ./docs/vale-styles
|
StylesPath = ./docs/vale-styles
|
||||||
|
|
||||||
[*.md]
|
[formats]
|
||||||
|
rb = md
|
||||||
|
|
||||||
|
[*.{md,rb}]
|
||||||
BasedOnStyles = Homebrew
|
BasedOnStyles = Homebrew
|
||||||
|
|||||||
@ -70,6 +70,11 @@ Style/Documentation:
|
|||||||
- version.rb
|
- version.rb
|
||||||
- tap.rb
|
- tap.rb
|
||||||
|
|
||||||
|
Homebrew/NegateInclude:
|
||||||
|
Exclude:
|
||||||
|
# YARD runs stand-alone.
|
||||||
|
- yard/docstring_parser.rb
|
||||||
|
|
||||||
Style/DocumentationMethod:
|
Style/DocumentationMethod:
|
||||||
Include:
|
Include:
|
||||||
- "formula.rb"
|
- "formula.rb"
|
||||||
|
|||||||
@ -16,6 +16,7 @@ end
|
|||||||
# installed gems (should all be require: false)
|
# installed gems (should all be require: false)
|
||||||
# ALL gems that are not vendored should be in a group
|
# ALL gems that are not vendored should be in a group
|
||||||
group :doc, optional: true do
|
group :doc, optional: true do
|
||||||
|
gem "redcarpet", require: false
|
||||||
gem "yard", require: false
|
gem "yard", require: false
|
||||||
gem "yard-sorbet", require: false
|
gem "yard-sorbet", require: false
|
||||||
end
|
end
|
||||||
|
|||||||
@ -53,6 +53,7 @@ GEM
|
|||||||
rbi (0.1.12)
|
rbi (0.1.12)
|
||||||
prism (>= 0.18.0, < 0.28)
|
prism (>= 0.18.0, < 0.28)
|
||||||
sorbet-runtime (>= 0.5.9204)
|
sorbet-runtime (>= 0.5.9204)
|
||||||
|
redcarpet (3.6.0)
|
||||||
regexp_parser (2.9.0)
|
regexp_parser (2.9.0)
|
||||||
rexml (3.2.6)
|
rexml (3.2.6)
|
||||||
rspec (3.13.0)
|
rspec (3.13.0)
|
||||||
@ -175,6 +176,7 @@ DEPENDENCIES
|
|||||||
patchelf
|
patchelf
|
||||||
plist
|
plist
|
||||||
pry
|
pry
|
||||||
|
redcarpet
|
||||||
rexml
|
rexml
|
||||||
rspec
|
rspec
|
||||||
rspec-github
|
rspec-github
|
||||||
|
|||||||
@ -60,7 +60,6 @@ class PATH
|
|||||||
@paths.join(File::PATH_SEPARATOR)
|
@paths.join(File::PATH_SEPARATOR)
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s = to_str
|
def to_s = to_str
|
||||||
|
|
||||||
|
|||||||
@ -6,9 +6,10 @@ require "cli/parser"
|
|||||||
module Homebrew
|
module Homebrew
|
||||||
# Subclass this to implement a `brew` command. This is preferred to declaring a named function in the `Homebrew`
|
# Subclass this to implement a `brew` command. This is preferred to declaring a named function in the `Homebrew`
|
||||||
# module, because:
|
# module, because:
|
||||||
|
#
|
||||||
# - Each Command lives in an isolated namespace.
|
# - Each Command lives in an isolated namespace.
|
||||||
# - Each Command implements a defined interface.
|
# - Each Command implements a defined interface.
|
||||||
# - `args` is available as an ivar, and thus does not need to be passed as an argument to helper methods.
|
# - `args` is available as an instance method and thus does not need to be passed as an argument to helper methods.
|
||||||
# - Subclasses no longer need to reference `CLI::Parser` or parse args explicitly.
|
# - Subclasses no longer need to reference `CLI::Parser` or parse args explicitly.
|
||||||
#
|
#
|
||||||
# To subclass, implement a `run` method and provide a `cmd_args` block to document the command and its allowed args.
|
# To subclass, implement a `run` method and provide a `cmd_args` block to document the command and its allowed args.
|
||||||
|
|||||||
@ -39,8 +39,8 @@ module Homebrew
|
|||||||
sig { returns(Pathname) }
|
sig { returns(Pathname) }
|
||||||
def self.gh_executable
|
def self.gh_executable
|
||||||
# NOTE: We disable HOMEBREW_VERIFY_ATTESTATIONS when installing `gh` itself,
|
# NOTE: We disable HOMEBREW_VERIFY_ATTESTATIONS when installing `gh` itself,
|
||||||
# to prevent a cycle during bootstrapping. This can eventually be resolved
|
# to prevent a cycle during bootstrapping. This can eventually be resolved
|
||||||
# by vendoring a pure-Ruby Sigstore verifier client.
|
# by vendoring a pure-Ruby Sigstore verifier client.
|
||||||
@gh_executable ||= T.let(with_env("HOMEBREW_VERIFY_ATTESTATIONS" => nil) do
|
@gh_executable ||= T.let(with_env("HOMEBREW_VERIFY_ATTESTATIONS" => nil) do
|
||||||
ensure_executable!("gh")
|
ensure_executable!("gh")
|
||||||
end, T.nilable(Pathname))
|
end, T.nilable(Pathname))
|
||||||
|
|||||||
@ -265,7 +265,7 @@ EOS
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# NOTE: the members of the array in the second arg must not have spaces!
|
# NOTE: The members of the array in the second arg must not have spaces!
|
||||||
check-array-membership() {
|
check-array-membership() {
|
||||||
local item=$1
|
local item=$1
|
||||||
shift
|
shift
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
# Note: that we use a non-standard config file name to reduce
|
# NOTE: We use a non-standard config file name to reduce name clashes with
|
||||||
# name clashes with other IRB config files like `.irbrc`.
|
# other IRB config files like `.irbrc`.
|
||||||
# Note #2: This doesn't work with system Ruby for some reason.
|
# NOTE: This doesn't work with system Ruby for some reason.
|
||||||
|
|
||||||
require 'irb/completion'
|
require 'irb/completion'
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@ class BuildEnvironment
|
|||||||
# DSL for specifying build environment settings.
|
# DSL for specifying build environment settings.
|
||||||
module DSL
|
module DSL
|
||||||
# Initialise @env for each class which may use this DSL (e.g. each formula subclass).
|
# Initialise @env for each class which may use this DSL (e.g. each formula subclass).
|
||||||
# `env` may never be called, and it needs to be initialised before the class is frozen.
|
# `env` may never be called and it needs to be initialised before the class is frozen.
|
||||||
def inherited(child)
|
def inherited(child)
|
||||||
super
|
super
|
||||||
child.instance_eval do
|
child.instance_eval do
|
||||||
|
|||||||
@ -9,16 +9,26 @@ class BuildOptions
|
|||||||
end
|
end
|
||||||
|
|
||||||
# True if a {Formula} is being built with a specific option.
|
# True if a {Formula} is being built with a specific option.
|
||||||
# <pre>args << "--i-want-spam" if build.with? "spam"
|
|
||||||
#
|
#
|
||||||
|
# ### Examples
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
|
# args << "--i-want-spam" if build.with? "spam"
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
# args << "--qt-gui" if build.with? "qt" # "--with-qt" ==> build.with? "qt"
|
# args << "--qt-gui" if build.with? "qt" # "--with-qt" ==> build.with? "qt"
|
||||||
|
# ```
|
||||||
#
|
#
|
||||||
# # If a formula presents a user with a choice, but the choice must be fulfilled:
|
# If a formula presents a user with a choice, but the choice must be fulfilled:
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
# if build.with? "example2"
|
# if build.with? "example2"
|
||||||
# args << "--with-example2"
|
# args << "--with-example2"
|
||||||
# else
|
# else
|
||||||
# args << "--with-example1"
|
# args << "--with-example1"
|
||||||
# end</pre>
|
# end
|
||||||
|
# ```
|
||||||
def with?(val)
|
def with?(val)
|
||||||
option_names = val.respond_to?(:option_names) ? val.option_names : [val]
|
option_names = val.respond_to?(:option_names) ? val.option_names : [val]
|
||||||
|
|
||||||
@ -34,7 +44,12 @@ class BuildOptions
|
|||||||
end
|
end
|
||||||
|
|
||||||
# True if a {Formula} is being built without a specific option.
|
# True if a {Formula} is being built without a specific option.
|
||||||
# <pre>args << "--no-spam-plz" if build.without? "spam"</pre>
|
#
|
||||||
|
# ### Example
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
|
# args << "--no-spam-plz" if build.without? "spam"
|
||||||
|
# ```
|
||||||
def without?(val)
|
def without?(val)
|
||||||
!with?(val)
|
!with?(val)
|
||||||
end
|
end
|
||||||
@ -45,19 +60,33 @@ class BuildOptions
|
|||||||
end
|
end
|
||||||
|
|
||||||
# True if a {Formula} is being built with {Formula.head} instead of {Formula.stable}.
|
# True if a {Formula} is being built with {Formula.head} instead of {Formula.stable}.
|
||||||
# <pre>args << "--some-new-stuff" if build.head?</pre>
|
#
|
||||||
# <pre># If there are multiple conditional arguments use a block instead of lines.
|
# ### Examples
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
|
# args << "--some-new-stuff" if build.head?
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# If there are multiple conditional arguments use a block instead of lines.
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
# if build.head?
|
# if build.head?
|
||||||
# args << "--i-want-pizza"
|
# args << "--i-want-pizza"
|
||||||
# args << "--and-a-cold-beer" if build.with? "cold-beer"
|
# args << "--and-a-cold-beer" if build.with? "cold-beer"
|
||||||
# end</pre>
|
# end
|
||||||
|
# ```
|
||||||
def head?
|
def head?
|
||||||
include? "HEAD"
|
include? "HEAD"
|
||||||
end
|
end
|
||||||
|
|
||||||
# True if a {Formula} is being built with {Formula.stable} instead of {Formula.head}.
|
# True if a {Formula} is being built with {Formula.stable} instead of {Formula.head}.
|
||||||
# This is the default.
|
# This is the default.
|
||||||
# <pre>args << "--some-beta" if build.head?</pre>
|
#
|
||||||
|
# ### Example
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
|
# args << "--some-beta" if build.head?
|
||||||
|
# ```
|
||||||
def stable?
|
def stable?
|
||||||
!head?
|
!head?
|
||||||
end
|
end
|
||||||
|
|||||||
@ -147,7 +147,6 @@ module Cask
|
|||||||
cask.config
|
cask.config
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
"#{summarize} (#{self.class.english_name})"
|
"#{summarize} (#{self.class.english_name})"
|
||||||
|
|||||||
@ -685,7 +685,7 @@ module Cask
|
|||||||
|
|
||||||
sig { void }
|
sig { void }
|
||||||
def audit_github_repository_archived
|
def audit_github_repository_archived
|
||||||
# Deprecated/disabled casks may have an archived repo.
|
# Deprecated/disabled casks may have an archived repository.
|
||||||
return if cask.discontinued? || cask.deprecated? || cask.disabled?
|
return if cask.discontinued? || cask.deprecated? || cask.disabled?
|
||||||
|
|
||||||
user, repo = get_repo_data(%r{https?://github\.com/([^/]+)/([^/]+)/?.*}) if online?
|
user, repo = get_repo_data(%r{https?://github\.com/([^/]+)/([^/]+)/?.*}) if online?
|
||||||
@ -699,7 +699,7 @@ module Cask
|
|||||||
|
|
||||||
sig { void }
|
sig { void }
|
||||||
def audit_gitlab_repository_archived
|
def audit_gitlab_repository_archived
|
||||||
# Deprecated/disabled casks may have an archived repo.
|
# Deprecated/disabled casks may have an archived repository.
|
||||||
return if cask.discontinued? || cask.deprecated? || cask.disabled?
|
return if cask.discontinued? || cask.deprecated? || cask.disabled?
|
||||||
|
|
||||||
user, repo = get_repo_data(%r{https?://gitlab\.com/([^/]+)/([^/]+)/?.*}) if online?
|
user, repo = get_repo_data(%r{https?://gitlab\.com/([^/]+)/([^/]+)/?.*}) if online?
|
||||||
|
|||||||
@ -78,7 +78,8 @@ module Cask
|
|||||||
@allow_reassignment = allow_reassignment
|
@allow_reassignment = allow_reassignment
|
||||||
@loaded_from_api = loaded_from_api
|
@loaded_from_api = loaded_from_api
|
||||||
@loader = loader
|
@loader = loader
|
||||||
# Sorbet has trouble with bound procs assigned to ivars: https://github.com/sorbet/sorbet/issues/6843
|
# Sorbet has trouble with bound procs assigned to instance variables:
|
||||||
|
# https://github.com/sorbet/sorbet/issues/6843
|
||||||
instance_variable_set(:@block, block)
|
instance_variable_set(:@block, block)
|
||||||
|
|
||||||
@default_config = config || Config.new
|
@default_config = config || Config.new
|
||||||
@ -323,11 +324,9 @@ module Cask
|
|||||||
end
|
end
|
||||||
|
|
||||||
# @api public
|
# @api public
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s = token
|
def to_s = token
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def inspect
|
def inspect
|
||||||
"#<Cask #{token}#{sourcefile_path&.to_s&.prepend(" ")}>"
|
"#<Cask #{token}#{sourcefile_path&.to_s&.prepend(" ")}>"
|
||||||
|
|||||||
@ -112,6 +112,16 @@ module Cask
|
|||||||
@token = cask.token
|
@token = cask.token
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Specifies the cask's name.
|
||||||
|
#
|
||||||
|
# NOTE: Multiple names can be specified.
|
||||||
|
#
|
||||||
|
# ### Example
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
|
# name "Visual Studio Code"
|
||||||
|
# ```
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
def name(*args)
|
def name(*args)
|
||||||
@name ||= []
|
@name ||= []
|
||||||
@ -120,6 +130,14 @@ module Cask
|
|||||||
@name.concat(args.flatten)
|
@name.concat(args.flatten)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Describes the cask.
|
||||||
|
#
|
||||||
|
# ### Example
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
|
# desc "Open-source code editor"
|
||||||
|
# ```
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
def desc(description = nil)
|
def desc(description = nil)
|
||||||
set_unique_stanza(:desc, description.nil?) { description }
|
set_unique_stanza(:desc, description.nil?) { description }
|
||||||
@ -146,6 +164,14 @@ module Cask
|
|||||||
raise CaskInvalidError.new(cask, "'#{stanza}' stanza failed with: #{e}")
|
raise CaskInvalidError.new(cask, "'#{stanza}' stanza failed with: #{e}")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Sets the cask's homepage.
|
||||||
|
#
|
||||||
|
# ### Example
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
|
# homepage "https://code.visualstudio.com/"
|
||||||
|
# ```
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
def homepage(homepage = nil)
|
def homepage(homepage = nil)
|
||||||
set_unique_stanza(:homepage, homepage.nil?) { homepage }
|
set_unique_stanza(:homepage, homepage.nil?) { homepage }
|
||||||
@ -201,6 +227,14 @@ module Cask
|
|||||||
@language_blocks.keys.flatten
|
@language_blocks.keys.flatten
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Sets the cask's download URL.
|
||||||
|
#
|
||||||
|
# ### Example
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
|
# url "https://update.code.visualstudio.com/#{version}/#{arch}/stable"
|
||||||
|
# ```
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
def url(*args, **options, &block)
|
def url(*args, **options, &block)
|
||||||
caller_location = T.must(caller_locations).fetch(0)
|
caller_location = T.must(caller_locations).fetch(0)
|
||||||
@ -214,6 +248,8 @@ module Cask
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Sets the cask's appcast URL.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
def appcast(*args, **kwargs)
|
def appcast(*args, **kwargs)
|
||||||
set_unique_stanza(:appcast, args.empty? && kwargs.empty?) do
|
set_unique_stanza(:appcast, args.empty? && kwargs.empty?) do
|
||||||
@ -222,6 +258,22 @@ module Cask
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Sets the cask's container type or nested container path.
|
||||||
|
#
|
||||||
|
# ### Examples
|
||||||
|
#
|
||||||
|
# The container is a nested disk image:
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
|
# container nested: "orca-#{version}.dmg"
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# The container should not be unarchived:
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
|
# container type: :naked
|
||||||
|
# ```
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
def container(**kwargs)
|
def container(**kwargs)
|
||||||
set_unique_stanza(:container, kwargs.empty?) do
|
set_unique_stanza(:container, kwargs.empty?) do
|
||||||
@ -229,6 +281,15 @@ module Cask
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Sets the cask's version.
|
||||||
|
#
|
||||||
|
# ### Example
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
|
# version "1.88.1"
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# @see DSL::Version
|
||||||
# @api public
|
# @api public
|
||||||
def version(arg = nil)
|
def version(arg = nil)
|
||||||
set_unique_stanza(:version, arg.nil?) do
|
set_unique_stanza(:version, arg.nil?) do
|
||||||
@ -240,6 +301,23 @@ module Cask
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Sets the cask's download checksum.
|
||||||
|
#
|
||||||
|
# ### Example
|
||||||
|
#
|
||||||
|
# For universal or single-architecture downloads:
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
|
# sha256 "7bdb497080ffafdfd8cc94d8c62b004af1be9599e865e5555e456e2681e150ca"
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# For architecture-dependent downloads:
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
|
# sha256 arm: "7bdb497080ffafdfd8cc94d8c62b004af1be9599e865e5555e456e2681e150ca",
|
||||||
|
# intel: "b3c1c2442480a0219b9e05cf91d03385858c20f04b764ec08a3fa83d1b27e7b2"
|
||||||
|
# ```
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
def sha256(arg = nil, arm: nil, intel: nil)
|
def sha256(arg = nil, arm: nil, intel: nil)
|
||||||
should_return = arg.nil? && arm.nil? && intel.nil?
|
should_return = arg.nil? && arm.nil? && intel.nil?
|
||||||
@ -259,6 +337,14 @@ module Cask
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Sets the cask's architecture strings.
|
||||||
|
#
|
||||||
|
# ### Example
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
|
# arch arm: "darwin-arm64", intel: "darwin"
|
||||||
|
# ```
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
def arch(arm: nil, intel: nil)
|
def arch(arm: nil, intel: nil)
|
||||||
should_return = arm.nil? && intel.nil?
|
should_return = arm.nil? && intel.nil?
|
||||||
@ -270,7 +356,10 @@ module Cask
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# `depends_on` uses a load method so that multiple stanzas can be merged.
|
# Declare dependencies and requirements for a cask.
|
||||||
|
#
|
||||||
|
# NOTE: Multiple dependencies can be specified.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
def depends_on(**kwargs)
|
def depends_on(**kwargs)
|
||||||
@depends_on ||= DSL::DependsOn.new
|
@depends_on ||= DSL::DependsOn.new
|
||||||
@ -284,9 +373,11 @@ module Cask
|
|||||||
@depends_on
|
@depends_on
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Declare conflicts that keep a cask from installing or working correctly.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
def conflicts_with(**kwargs)
|
def conflicts_with(**kwargs)
|
||||||
# TODO: remove this constraint, and instead merge multiple conflicts_with stanzas
|
# TODO: Remove this constraint and instead merge multiple `conflicts_with` stanzas
|
||||||
set_unique_stanza(:conflicts_with, kwargs.empty?) { DSL::ConflictsWith.new(**kwargs) }
|
set_unique_stanza(:conflicts_with, kwargs.empty?) { DSL::ConflictsWith.new(**kwargs) }
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -298,6 +389,8 @@ module Cask
|
|||||||
cask.caskroom_path
|
cask.caskroom_path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The staged location for this cask, including version number.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
def staged_path
|
def staged_path
|
||||||
return @staged_path if @staged_path
|
return @staged_path if @staged_path
|
||||||
@ -306,6 +399,8 @@ module Cask
|
|||||||
@staged_path = caskroom_path.join(cask_version.to_s)
|
@staged_path = caskroom_path.join(cask_version.to_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Provide the user with cask-specific information at install time.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
def caveats(*strings, &block)
|
def caveats(*strings, &block)
|
||||||
@caveats ||= DSL::Caveats.new(cask)
|
@caveats ||= DSL::Caveats.new(cask)
|
||||||
@ -326,11 +421,15 @@ module Cask
|
|||||||
@caveats&.discontinued? == true
|
@caveats&.discontinued? == true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Asserts that the cask artifacts auto-update.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
def auto_updates(auto_updates = nil)
|
def auto_updates(auto_updates = nil)
|
||||||
set_unique_stanza(:auto_updates, auto_updates.nil?) { auto_updates }
|
set_unique_stanza(:auto_updates, auto_updates.nil?) { auto_updates }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Automatically fetch the latest version of a cask from changelogs.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
def livecheck(&block)
|
def livecheck(&block)
|
||||||
@livecheck ||= Livecheck.new(cask)
|
@livecheck ||= Livecheck.new(cask)
|
||||||
@ -344,6 +443,10 @@ module Cask
|
|||||||
@livecheck.instance_eval(&block)
|
@livecheck.instance_eval(&block)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Declare that a cask is no longer functional or supported.
|
||||||
|
#
|
||||||
|
# NOTE: A warning will be shown when trying to install this cask.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
def deprecate!(date:, because:)
|
def deprecate!(date:, because:)
|
||||||
@deprecation_date = Date.parse(date)
|
@deprecation_date = Date.parse(date)
|
||||||
@ -353,6 +456,10 @@ module Cask
|
|||||||
@deprecated = true
|
@deprecated = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Declare that a cask is no longer functional or supported.
|
||||||
|
#
|
||||||
|
# NOTE: An error will be thrown when trying to install this cask.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
def disable!(date:, because:)
|
def disable!(date:, because:)
|
||||||
@disable_date = Date.parse(date)
|
@disable_date = Date.parse(date)
|
||||||
@ -405,6 +512,8 @@ module Cask
|
|||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The directory `app`s are installed into.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
def appdir
|
def appdir
|
||||||
return HOMEBREW_CASK_APPDIR_PLACEHOLDER if Cask.generating_hash?
|
return HOMEBREW_CASK_APPDIR_PLACEHOLDER if Cask.generating_hash?
|
||||||
|
|||||||
@ -37,7 +37,6 @@ module Cask
|
|||||||
|
|
||||||
private_class_method :caveat
|
private_class_method :caveat
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
(@custom_caveats + @built_in_caveats.values).join("\n")
|
(@custom_caveats + @built_in_caveats.values).join("\n")
|
||||||
|
|||||||
@ -27,7 +27,6 @@ module Cask
|
|||||||
pairs.to_yaml
|
pairs.to_yaml
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s = pairs.inspect
|
def to_s = pairs.inspect
|
||||||
end
|
end
|
||||||
|
|||||||
@ -9,8 +9,8 @@ module Cask
|
|||||||
class Postflight < Base
|
class Postflight < Base
|
||||||
include Staged
|
include Staged
|
||||||
|
|
||||||
def suppress_move_to_applications(_options = {})
|
def suppress_move_to_applications(**_options)
|
||||||
odisabled "Cask::DSL#suppress_move_to_applications"
|
odisabled "`Cask::DSL::Postflight#suppress_move_to_applications`"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -94,70 +94,94 @@ module Cask
|
|||||||
to_s == "latest"
|
to_s == "latest"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The major version.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
sig { returns(T.self_type) }
|
sig { returns(T.self_type) }
|
||||||
def major
|
def major
|
||||||
version { slice(MAJOR_MINOR_PATCH_REGEX, 1) }
|
version { slice(MAJOR_MINOR_PATCH_REGEX, 1) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The minor version.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
sig { returns(T.self_type) }
|
sig { returns(T.self_type) }
|
||||||
def minor
|
def minor
|
||||||
version { slice(MAJOR_MINOR_PATCH_REGEX, 2) }
|
version { slice(MAJOR_MINOR_PATCH_REGEX, 2) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The patch version.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
sig { returns(T.self_type) }
|
sig { returns(T.self_type) }
|
||||||
def patch
|
def patch
|
||||||
version { slice(MAJOR_MINOR_PATCH_REGEX, 3) }
|
version { slice(MAJOR_MINOR_PATCH_REGEX, 3) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The major and minor version.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
sig { returns(T.self_type) }
|
sig { returns(T.self_type) }
|
||||||
def major_minor
|
def major_minor
|
||||||
version { [major, minor].reject(&:empty?).join(".") }
|
version { [major, minor].reject(&:empty?).join(".") }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The major, minor and patch version.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
sig { returns(T.self_type) }
|
sig { returns(T.self_type) }
|
||||||
def major_minor_patch
|
def major_minor_patch
|
||||||
version { [major, minor, patch].reject(&:empty?).join(".") }
|
version { [major, minor, patch].reject(&:empty?).join(".") }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The minor and patch version.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
sig { returns(T.self_type) }
|
sig { returns(T.self_type) }
|
||||||
def minor_patch
|
def minor_patch
|
||||||
version { [minor, patch].reject(&:empty?).join(".") }
|
version { [minor, patch].reject(&:empty?).join(".") }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The comma separated values of the version as array.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
sig { returns(T::Array[Version]) } # Only top-level T.self_type is supported https://sorbet.org/docs/self-type
|
sig { returns(T::Array[Version]) } # Only top-level T.self_type is supported https://sorbet.org/docs/self-type
|
||||||
def csv
|
def csv
|
||||||
split(",").map { self.class.new(_1) }
|
split(",").map { self.class.new(_1) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The version part before the first comma.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
sig { returns(T.self_type) }
|
sig { returns(T.self_type) }
|
||||||
def before_comma
|
def before_comma
|
||||||
version { split(",", 2).first }
|
version { split(",", 2).first }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The version part after the first comma.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
sig { returns(T.self_type) }
|
sig { returns(T.self_type) }
|
||||||
def after_comma
|
def after_comma
|
||||||
version { split(",", 2).second }
|
version { split(",", 2).second }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The version without any dividers.
|
||||||
|
#
|
||||||
|
# @see DIVIDER_REGEX
|
||||||
# @api public
|
# @api public
|
||||||
sig { returns(T.self_type) }
|
sig { returns(T.self_type) }
|
||||||
def no_dividers
|
def no_dividers
|
||||||
version { gsub(DIVIDER_REGEX, "") }
|
version { gsub(DIVIDER_REGEX, "") }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The version with the given record separator removed from the end.
|
||||||
|
#
|
||||||
|
# @see String#chomp
|
||||||
# @api public
|
# @api public
|
||||||
sig { params(separator: T.nilable(String)).returns(T.self_type) }
|
sig { params(separator: String).returns(T.self_type) }
|
||||||
def chomp(separator = nil)
|
def chomp(separator = T.unsafe(nil))
|
||||||
version { to_s.chomp(T.unsafe(separator)) }
|
version { to_s.chomp(separator) }
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|||||||
@ -13,7 +13,6 @@ module Cask
|
|||||||
@errors = errors
|
@errors = errors
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
<<~EOS
|
<<~EOS
|
||||||
@ -41,7 +40,6 @@ module Cask
|
|||||||
|
|
||||||
# Error when a cask is not installed.
|
# Error when a cask is not installed.
|
||||||
class CaskNotInstalledError < AbstractCaskErrorWithToken
|
class CaskNotInstalledError < AbstractCaskErrorWithToken
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
"Cask '#{token}' is not installed."
|
"Cask '#{token}' is not installed."
|
||||||
@ -57,7 +55,6 @@ module Cask
|
|||||||
@message = message
|
@message = message
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
"Cask '#{token}' has been #{message}"
|
"Cask '#{token}' has been #{message}"
|
||||||
@ -73,7 +70,6 @@ module Cask
|
|||||||
@conflicting_cask = conflicting_cask
|
@conflicting_cask = conflicting_cask
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
"Cask '#{token}' conflicts with '#{conflicting_cask}'."
|
"Cask '#{token}' conflicts with '#{conflicting_cask}'."
|
||||||
@ -82,7 +78,6 @@ module Cask
|
|||||||
|
|
||||||
# Error when a cask is not available.
|
# Error when a cask is not available.
|
||||||
class CaskUnavailableError < AbstractCaskErrorWithToken
|
class CaskUnavailableError < AbstractCaskErrorWithToken
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
"Cask '#{token}' is unavailable#{reason.empty? ? "." : ": #{reason}"}"
|
"Cask '#{token}' is unavailable#{reason.empty? ? "." : ": #{reason}"}"
|
||||||
@ -91,7 +86,6 @@ module Cask
|
|||||||
|
|
||||||
# Error when a cask is unreadable.
|
# Error when a cask is unreadable.
|
||||||
class CaskUnreadableError < CaskUnavailableError
|
class CaskUnreadableError < CaskUnavailableError
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
"Cask '#{token}' is unreadable#{reason.empty? ? "." : ": #{reason}"}"
|
"Cask '#{token}' is unreadable#{reason.empty? ? "." : ": #{reason}"}"
|
||||||
@ -107,7 +101,6 @@ module Cask
|
|||||||
@tap = tap
|
@tap = tap
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
s = super
|
s = super
|
||||||
@ -142,7 +135,6 @@ module Cask
|
|||||||
|
|
||||||
# Error when a cask already exists.
|
# Error when a cask already exists.
|
||||||
class CaskAlreadyCreatedError < AbstractCaskErrorWithToken
|
class CaskAlreadyCreatedError < AbstractCaskErrorWithToken
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
%Q(Cask '#{token}' already exists. Run #{Formatter.identifier("brew edit --cask #{token}")} to edit it.)
|
%Q(Cask '#{token}' already exists. Run #{Formatter.identifier("brew edit --cask #{token}")} to edit it.)
|
||||||
@ -151,7 +143,6 @@ module Cask
|
|||||||
|
|
||||||
# Error when there is a cyclic cask dependency.
|
# Error when there is a cyclic cask dependency.
|
||||||
class CaskCyclicDependencyError < AbstractCaskErrorWithToken
|
class CaskCyclicDependencyError < AbstractCaskErrorWithToken
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
"Cask '#{token}' includes cyclic dependencies on other Casks#{reason.empty? ? "." : ": #{reason}"}"
|
"Cask '#{token}' includes cyclic dependencies on other Casks#{reason.empty? ? "." : ": #{reason}"}"
|
||||||
@ -160,7 +151,6 @@ module Cask
|
|||||||
|
|
||||||
# Error when a cask depends on itself.
|
# Error when a cask depends on itself.
|
||||||
class CaskSelfReferencingDependencyError < CaskCyclicDependencyError
|
class CaskSelfReferencingDependencyError < CaskCyclicDependencyError
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
"Cask '#{token}' depends on itself."
|
"Cask '#{token}' depends on itself."
|
||||||
@ -169,7 +159,6 @@ module Cask
|
|||||||
|
|
||||||
# Error when no cask is specified.
|
# Error when no cask is specified.
|
||||||
class CaskUnspecifiedError < CaskError
|
class CaskUnspecifiedError < CaskError
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
"This command requires a Cask token."
|
"This command requires a Cask token."
|
||||||
@ -178,7 +167,6 @@ module Cask
|
|||||||
|
|
||||||
# Error when a cask is invalid.
|
# Error when a cask is invalid.
|
||||||
class CaskInvalidError < AbstractCaskErrorWithToken
|
class CaskInvalidError < AbstractCaskErrorWithToken
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
"Cask '#{token}' definition is invalid#{reason.empty? ? "." : ": #{reason}"}"
|
"Cask '#{token}' definition is invalid#{reason.empty? ? "." : ": #{reason}"}"
|
||||||
@ -203,7 +191,6 @@ module Cask
|
|||||||
@reason = reason
|
@reason = reason
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
s = +"Failed to quarantine #{path}."
|
s = +"Failed to quarantine #{path}."
|
||||||
@ -220,7 +207,6 @@ module Cask
|
|||||||
|
|
||||||
# Error while propagating quarantine information to subdirectories.
|
# Error while propagating quarantine information to subdirectories.
|
||||||
class CaskQuarantinePropagationError < CaskQuarantineError
|
class CaskQuarantinePropagationError < CaskQuarantineError
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
s = +"Failed to quarantine one or more files within #{path}."
|
s = +"Failed to quarantine one or more files within #{path}."
|
||||||
@ -237,7 +223,6 @@ module Cask
|
|||||||
|
|
||||||
# Error while removing quarantine information.
|
# Error while removing quarantine information.
|
||||||
class CaskQuarantineReleaseError < CaskQuarantineError
|
class CaskQuarantineReleaseError < CaskQuarantineError
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
s = +"Failed to release #{path} from quarantine."
|
s = +"Failed to release #{path} from quarantine."
|
||||||
|
|||||||
@ -17,22 +17,32 @@ module Cask
|
|||||||
extend Forwardable
|
extend Forwardable
|
||||||
def_delegators :uri, :path, :scheme, :to_s
|
def_delegators :uri, :path, :scheme, :to_s
|
||||||
|
|
||||||
# @api public
|
|
||||||
sig {
|
sig {
|
||||||
params(
|
params(
|
||||||
uri: T.any(URI::Generic, String),
|
uri: T.any(URI::Generic, String),
|
||||||
|
# @api public
|
||||||
verified: T.nilable(String),
|
verified: T.nilable(String),
|
||||||
|
# @api public
|
||||||
using: T.any(Class, Symbol, NilClass),
|
using: T.any(Class, Symbol, NilClass),
|
||||||
|
# @api public
|
||||||
tag: T.nilable(String),
|
tag: T.nilable(String),
|
||||||
|
# @api public
|
||||||
branch: T.nilable(String),
|
branch: T.nilable(String),
|
||||||
|
# @api public
|
||||||
revisions: T.nilable(T::Array[String]),
|
revisions: T.nilable(T::Array[String]),
|
||||||
|
# @api public
|
||||||
revision: T.nilable(String),
|
revision: T.nilable(String),
|
||||||
|
# @api public
|
||||||
trust_cert: T.nilable(T::Boolean),
|
trust_cert: T.nilable(T::Boolean),
|
||||||
|
# @api public
|
||||||
cookies: T.nilable(T::Hash[String, String]),
|
cookies: T.nilable(T::Hash[String, String]),
|
||||||
referer: T.nilable(T.any(URI::Generic, String)),
|
referer: T.nilable(T.any(URI::Generic, String)),
|
||||||
|
# @api public
|
||||||
header: T.nilable(T.any(String, T::Array[String])),
|
header: T.nilable(T.any(String, T::Array[String])),
|
||||||
user_agent: T.nilable(T.any(Symbol, String)),
|
user_agent: T.nilable(T.any(Symbol, String)),
|
||||||
|
# @api public
|
||||||
data: T.nilable(T::Hash[String, String]),
|
data: T.nilable(T::Hash[String, String]),
|
||||||
|
# @api public
|
||||||
only_path: T.nilable(String),
|
only_path: T.nilable(String),
|
||||||
).void
|
).void
|
||||||
}
|
}
|
||||||
@ -77,8 +87,19 @@ module Cask
|
|||||||
end
|
end
|
||||||
|
|
||||||
class BlockDSL
|
class BlockDSL
|
||||||
# To access URL associated with page contents.
|
# Allow accessing the URL associated with page contents.
|
||||||
module PageWithURL
|
module PageWithURL
|
||||||
|
# Get the URL of the fetched page.
|
||||||
|
#
|
||||||
|
# ### Example
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
|
# url "https://example.org/download" do |page|
|
||||||
|
# file = page[/href="([^"]+.dmg)"/, 1]
|
||||||
|
# URL.join(page.url, file)
|
||||||
|
# end
|
||||||
|
# ```
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
sig { returns(URI::Generic) }
|
sig { returns(URI::Generic) }
|
||||||
attr_accessor :url
|
attr_accessor :url
|
||||||
@ -87,12 +108,12 @@ module Cask
|
|||||||
sig {
|
sig {
|
||||||
params(
|
params(
|
||||||
uri: T.nilable(T.any(URI::Generic, String)),
|
uri: T.nilable(T.any(URI::Generic, String)),
|
||||||
dsl: T.nilable(::Cask::DSL),
|
dsl: ::Cask::DSL,
|
||||||
block: T.proc.params(arg0: T.all(String, PageWithURL))
|
block: T.proc.params(arg0: T.all(String, PageWithURL))
|
||||||
.returns(T.any(T.any(URI::Generic, String), [T.any(URI::Generic, String), Hash])),
|
.returns(T.any(T.any(URI::Generic, String), [T.any(URI::Generic, String), Hash])),
|
||||||
).void
|
).void
|
||||||
}
|
}
|
||||||
def initialize(uri, dsl: nil, &block)
|
def initialize(uri, dsl:, &block)
|
||||||
@uri = uri
|
@uri = uri
|
||||||
@dsl = dsl
|
@dsl = dsl
|
||||||
@block = block
|
@block = block
|
||||||
@ -114,6 +135,8 @@ module Cask
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Allows calling a nested `url` stanza in a `url do` block.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
sig {
|
sig {
|
||||||
params(
|
params(
|
||||||
@ -123,10 +146,12 @@ module Cask
|
|||||||
).returns(T.any(T.any(URI::Generic, String), [T.any(URI::Generic, String), Hash]))
|
).returns(T.any(T.any(URI::Generic, String), [T.any(URI::Generic, String), Hash]))
|
||||||
}
|
}
|
||||||
def url(uri, &block)
|
def url(uri, &block)
|
||||||
self.class.new(uri, &block).call
|
self.class.new(uri, dsl: @dsl, &block).call
|
||||||
end
|
end
|
||||||
private :url
|
private :url
|
||||||
|
|
||||||
|
# This allows calling DSL methods from inside a `url` block.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
def method_missing(method, *args, &block)
|
def method_missing(method, *args, &block)
|
||||||
if @dsl.respond_to?(method)
|
if @dsl.respond_to?(method)
|
||||||
@ -135,10 +160,12 @@ module Cask
|
|||||||
super
|
super
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
private :method_missing
|
||||||
|
|
||||||
def respond_to_missing?(method, include_all)
|
def respond_to_missing?(method, include_all)
|
||||||
@dsl.respond_to?(method, include_all) || super
|
@dsl.respond_to?(method, include_all) || super
|
||||||
end
|
end
|
||||||
|
private :respond_to_missing?
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {
|
sig {
|
||||||
@ -187,7 +214,7 @@ module Cask
|
|||||||
super(
|
super(
|
||||||
if block
|
if block
|
||||||
LazyObject.new do
|
LazyObject.new do
|
||||||
uri2, options = *BlockDSL.new(uri, dsl:, &block).call
|
uri2, options = *BlockDSL.new(uri, dsl: T.must(dsl), &block).call
|
||||||
options ||= {}
|
options ||= {}
|
||||||
DSL.new(uri2, **options)
|
DSL.new(uri2, **options)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -68,9 +68,9 @@ module Cask
|
|||||||
unless tried_permissions
|
unless tried_permissions
|
||||||
print_stderr = Context.current.debug? || Context.current.verbose?
|
print_stderr = Context.current.debug? || Context.current.verbose?
|
||||||
# TODO: Better handling for the case where path is a symlink.
|
# TODO: Better handling for the case where path is a symlink.
|
||||||
# The -h and -R flags cannot be combined, and behavior is
|
# The `-h` and `-R` flags cannot be combined and behavior is
|
||||||
# dependent on whether the file argument has a trailing
|
# dependent on whether the file argument has a trailing
|
||||||
# slash. This should do the right thing, but is fragile.
|
# slash. This should do the right thing, but is fragile.
|
||||||
command.run("/usr/bin/chflags",
|
command.run("/usr/bin/chflags",
|
||||||
print_stderr:,
|
print_stderr:,
|
||||||
args: command_args + ["--", "000", path])
|
args: command_args + ["--", "000", path])
|
||||||
@ -87,7 +87,7 @@ module Cask
|
|||||||
unless tried_ownership
|
unless tried_ownership
|
||||||
# in case of ownership problems
|
# in case of ownership problems
|
||||||
# TODO: Further examine files to see if ownership is the problem
|
# TODO: Further examine files to see if ownership is the problem
|
||||||
# before using sudo+chown
|
# before using `sudo` and `chown`.
|
||||||
ohai "Using sudo to gain ownership of path '#{path}'"
|
ohai "Using sudo to gain ownership of path '#{path}'"
|
||||||
command.run("/usr/sbin/chown",
|
command.run("/usr/sbin/chown",
|
||||||
args: command_args + ["--", User.current, path],
|
args: command_args + ["--", User.current, path],
|
||||||
|
|||||||
@ -25,27 +25,28 @@ class Cleaner
|
|||||||
def clean
|
def clean
|
||||||
ObserverPathnameExtension.reset_counts!
|
ObserverPathnameExtension.reset_counts!
|
||||||
|
|
||||||
# Many formulae include 'lib/charset.alias', but it is not strictly needed
|
# Many formulae include `lib/charset.alias`, but it is not strictly needed
|
||||||
# and will conflict if more than one formula provides it
|
# and will conflict if more than one formula provides it.
|
||||||
observe_file_removal @formula.lib/"charset.alias"
|
observe_file_removal @formula.lib/"charset.alias"
|
||||||
|
|
||||||
[@formula.bin, @formula.sbin, @formula.lib].each { |dir| clean_dir(dir) if dir.exist? }
|
[@formula.bin, @formula.sbin, @formula.lib].each { |dir| clean_dir(dir) if dir.exist? }
|
||||||
|
|
||||||
# Get rid of any info 'dir' files, so they don't conflict at the link stage
|
# Get rid of any info `dir` files, so they don't conflict at the link stage.
|
||||||
#
|
#
|
||||||
# The 'dir' files come in at least 3 locations:
|
# The `dir` files come in at least 3 locations:
|
||||||
#
|
#
|
||||||
# 1. 'info/dir'
|
# 1. `info/dir`
|
||||||
# 2. 'info/#{name}/dir'
|
# 2. `info/#{name}/dir`
|
||||||
# 3. 'info/#{arch}/dir'
|
# 3. `info/#{arch}/dir`
|
||||||
#
|
#
|
||||||
# Of these 3 only 'info/#{name}/dir' is safe to keep since the rest will
|
# Of these 3 only `info/#{name}/dir` is safe to keep since the rest will
|
||||||
# conflict with other formulae because they use a shared location.
|
# conflict with other formulae because they use a shared location.
|
||||||
#
|
#
|
||||||
# See [cleaner: recursively delete info `dir`s by gromgit · Pull Request
|
# See
|
||||||
# #11597][1], [emacs 28.1 bottle does not contain `dir` file · Issue
|
# [cleaner: recursively delete info `dir`s][1],
|
||||||
# #100190][2], and [Keep `info/#{f.name}/dir` files in cleaner by
|
# [emacs 28.1 bottle does not contain `dir` file][2] and
|
||||||
# timvisher][3] for more info.
|
# [Keep `info/#{f.name}/dir` files in cleaner][3]
|
||||||
|
# for more info.
|
||||||
#
|
#
|
||||||
# [1]: https://github.com/Homebrew/brew/pull/11597
|
# [1]: https://github.com/Homebrew/brew/pull/11597
|
||||||
# [2]: https://github.com/Homebrew/homebrew-core/issues/100190
|
# [2]: https://github.com/Homebrew/homebrew-core/issues/100190
|
||||||
@ -114,15 +115,15 @@ class Cleaner
|
|||||||
# created as part of installing any Perl module.
|
# created as part of installing any Perl module.
|
||||||
PERL_BASENAMES = Set.new(%w[perllocal.pod .packlist]).freeze
|
PERL_BASENAMES = Set.new(%w[perllocal.pod .packlist]).freeze
|
||||||
|
|
||||||
# Clean a top-level (bin, sbin, lib) directory, recursively, by fixing file
|
# Clean a top-level (`bin`, `sbin`, `lib`) directory, recursively, by fixing file
|
||||||
# permissions and removing .la files, unless the files (or parent
|
# permissions and removing .la files, unless the files (or parent
|
||||||
# directories) are protected by skip_clean.
|
# directories) are protected by skip_clean.
|
||||||
#
|
#
|
||||||
# bin and sbin should not have any subdirectories; if either do that is
|
# `bin` and `sbin` should not have any subdirectories; if either do that is
|
||||||
# caught as an audit warning
|
# caught as an audit warning.
|
||||||
#
|
#
|
||||||
# lib may have a large directory tree (see Erlang for instance), and
|
# `lib` may have a large directory tree (see Erlang for instance) and
|
||||||
# clean_dir applies cleaning rules to the entire tree
|
# clean_dir applies cleaning rules to the entire tree.
|
||||||
sig { params(directory: Pathname).void }
|
sig { params(directory: Pathname).void }
|
||||||
def clean_dir(directory)
|
def clean_dir(directory)
|
||||||
directory.find do |path|
|
directory.find do |path|
|
||||||
@ -137,7 +138,7 @@ class Cleaner
|
|||||||
elsif path.symlink?
|
elsif path.symlink?
|
||||||
# Skip it.
|
# Skip it.
|
||||||
else
|
else
|
||||||
# Set permissions for executables and non-executables
|
# Set permissions for executables and non-executables.
|
||||||
perms = if executable_path?(path)
|
perms = if executable_path?(path)
|
||||||
0555
|
0555
|
||||||
else
|
else
|
||||||
|
|||||||
@ -376,7 +376,7 @@ module Homebrew
|
|||||||
def cache_files
|
def cache_files
|
||||||
files = cache.directory? ? cache.children : []
|
files = cache.directory? ? cache.children : []
|
||||||
cask_files = (cache/"Cask").directory? ? (cache/"Cask").children : []
|
cask_files = (cache/"Cask").directory? ? (cache/"Cask").children : []
|
||||||
api_source_files = (cache/"api-source").glob("*/*/*/*/*") # org/repo/git_head/type/file.rb
|
api_source_files = (cache/"api-source").glob("*/*/*/*/*") # `<org>/<repo>/<git_head>/<type>/<token>.rb`
|
||||||
gh_actions_artifacts = (cache/"gh-actions-artifact").directory? ? (cache/"gh-actions-artifact").children : []
|
gh_actions_artifacts = (cache/"gh-actions-artifact").directory? ? (cache/"gh-actions-artifact").children : []
|
||||||
|
|
||||||
files.map { |path| { path:, type: nil } } +
|
files.map { |path| { path:, type: nil } } +
|
||||||
@ -571,8 +571,8 @@ module Homebrew
|
|||||||
HOMEBREW_PREFIX.glob("lib/python*/site-packages").each do |site_packages|
|
HOMEBREW_PREFIX.glob("lib/python*/site-packages").each do |site_packages|
|
||||||
site_packages.each_child do |child|
|
site_packages.each_child do |child|
|
||||||
next unless child.directory?
|
next unless child.directory?
|
||||||
# TODO: Work out a sensible way to clean up pip's, setuptools', and wheel's
|
# TODO: Work out a sensible way to clean up `pip`'s, `setuptools`' and `wheel`'s
|
||||||
# {dist,site}-info directories. Alternatively, consider always removing
|
# `{dist,site}-info` directories. Alternatively, consider always removing
|
||||||
# all `-info` directories, because we may not be making use of them.
|
# all `-info` directories, because we may not be making use of them.
|
||||||
next if child.basename.to_s.end_with?("-info")
|
next if child.basename.to_s.end_with?("-info")
|
||||||
|
|
||||||
|
|||||||
@ -95,7 +95,7 @@ module Homebrew
|
|||||||
dirs = HOMEBREW_PREFIX.subdirs.map { |dir| dir.basename.to_s }
|
dirs = HOMEBREW_PREFIX.subdirs.map { |dir| dir.basename.to_s }
|
||||||
dirs -= %w[Library Cellar Caskroom .git]
|
dirs -= %w[Library Cellar Caskroom .git]
|
||||||
|
|
||||||
# Exclude cache, logs, and repository, if they are located under the prefix.
|
# Exclude cache, logs and repository, if they are located under the prefix.
|
||||||
[HOMEBREW_CACHE, HOMEBREW_LOGS, HOMEBREW_REPOSITORY].each do |dir|
|
[HOMEBREW_CACHE, HOMEBREW_LOGS, HOMEBREW_REPOSITORY].each do |dir|
|
||||||
dirs.delete dir.relative_path_from(HOMEBREW_PREFIX).to_s
|
dirs.delete dir.relative_path_from(HOMEBREW_PREFIX).to_s
|
||||||
end
|
end
|
||||||
|
|||||||
@ -13,7 +13,7 @@ module Homebrew
|
|||||||
cmd_args do
|
cmd_args do
|
||||||
description <<~EOS
|
description <<~EOS
|
||||||
List installed casks and formulae that have an updated version available. By default, version
|
List installed casks and formulae that have an updated version available. By default, version
|
||||||
information is displayed in interactive shells, and suppressed otherwise.
|
information is displayed in interactive shells and suppressed otherwise.
|
||||||
EOS
|
EOS
|
||||||
switch "-q", "--quiet",
|
switch "-q", "--quiet",
|
||||||
description: "List only the names of outdated kegs (takes precedence over `--verbose`)."
|
description: "List only the names of outdated kegs (takes precedence over `--verbose`)."
|
||||||
|
|||||||
@ -756,7 +756,7 @@ class ReporterHub
|
|||||||
def dump(auto_update: false)
|
def dump(auto_update: false)
|
||||||
report_all = ENV["HOMEBREW_UPDATE_REPORT_ALL_FORMULAE"].present?
|
report_all = ENV["HOMEBREW_UPDATE_REPORT_ALL_FORMULAE"].present?
|
||||||
if report_all && !Homebrew::EnvConfig.no_install_from_api?
|
if report_all && !Homebrew::EnvConfig.no_install_from_api?
|
||||||
odisabled "HOMEBREW_UPDATE_REPORT_ALL_FORMULAE"
|
odisabled "`HOMEBREW_UPDATE_REPORT_ALL_FORMULAE`"
|
||||||
opoo "This will not report all formulae because Homebrew cannot get this data from the API."
|
opoo "This will not report all formulae because Homebrew cannot get this data from the API."
|
||||||
report_all = false
|
report_all = false
|
||||||
end
|
end
|
||||||
|
|||||||
@ -65,7 +65,6 @@ class CompilerFailure
|
|||||||
type == compiler.type && version_matched
|
type == compiler.type && version_matched
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def inspect
|
def inspect
|
||||||
"#<#{self.class.name}: #{type} #{version}>"
|
"#<#{self.class.name}: #{type} #{version}>"
|
||||||
|
|||||||
@ -22,7 +22,6 @@ class CxxStdlib
|
|||||||
type.to_s.gsub(/cxx$/, "c++")
|
type.to_s.gsub(/cxx$/, "c++")
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def inspect
|
def inspect
|
||||||
"#<#{self.class.name}: #{compiler} #{type}>"
|
"#<#{self.class.name}: #{compiler} #{type}>"
|
||||||
|
|||||||
@ -35,7 +35,6 @@ class Dependencies < SimpleDelegator
|
|||||||
self.class.new(*__getobj__.reject { |dep| dep.uses_from_macos? && dep.use_macos_install? })
|
self.class.new(*__getobj__.reject { |dep| dep.uses_from_macos? && dep.use_macos_install? })
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def inspect
|
def inspect
|
||||||
"#<#{self.class.name}: #{__getobj__}>"
|
"#<#{self.class.name}: #{__getobj__}>"
|
||||||
@ -62,7 +61,6 @@ class Requirements < SimpleDelegator
|
|||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def inspect
|
def inspect
|
||||||
"#<#{self.class.name}: {#{__getobj__.to_a.join(", ")}}>"
|
"#<#{self.class.name}: {#{__getobj__.to_a.join(", ")}}>"
|
||||||
|
|||||||
@ -33,7 +33,7 @@ module DependenciesHelpers
|
|||||||
end
|
end
|
||||||
|
|
||||||
# If a tap isn't installed, we can't find the dependencies of one of
|
# If a tap isn't installed, we can't find the dependencies of one of
|
||||||
# its formulae, and an exception will be thrown if we try.
|
# its formulae and an exception will be thrown if we try.
|
||||||
Dependency.keep_but_prune_recursive_deps if klass == Dependency && dep.tap && !dep.tap.installed?
|
Dependency.keep_but_prune_recursive_deps if klass == Dependency && dep.tap && !dep.tap.installed?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -4,6 +4,8 @@
|
|||||||
require "dependable"
|
require "dependable"
|
||||||
|
|
||||||
# A dependency on another Homebrew formula.
|
# A dependency on another Homebrew formula.
|
||||||
|
#
|
||||||
|
# @api internal
|
||||||
class Dependency
|
class Dependency
|
||||||
extend Forwardable
|
extend Forwardable
|
||||||
include Dependable
|
include Dependable
|
||||||
@ -94,11 +96,9 @@ class Dependency
|
|||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s = name
|
def to_s = name
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def inspect
|
def inspect
|
||||||
"#<#{self.class.name}: #{name.inspect} #{tags.inspect}>"
|
"#<#{self.class.name}: #{name.inspect} #{tags.inspect}>"
|
||||||
@ -115,6 +115,8 @@ class Dependency
|
|||||||
# the list.
|
# the list.
|
||||||
# The default filter, which is applied when a block is not given, omits
|
# The default filter, which is applied when a block is not given, omits
|
||||||
# optionals and recommends based on what the dependent has asked for
|
# optionals and recommends based on what the dependent has asked for
|
||||||
|
#
|
||||||
|
# @api internal
|
||||||
def expand(dependent, deps = dependent.deps, cache_key: nil, &block)
|
def expand(dependent, deps = dependent.deps, cache_key: nil, &block)
|
||||||
# Keep track dependencies to avoid infinite cyclic dependency recursion.
|
# Keep track dependencies to avoid infinite cyclic dependency recursion.
|
||||||
@expand_stack ||= []
|
@expand_stack ||= []
|
||||||
@ -181,6 +183,8 @@ class Dependency
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Keep a dependency, but prune its dependencies.
|
# Keep a dependency, but prune its dependencies.
|
||||||
|
#
|
||||||
|
# @api internal
|
||||||
sig { void }
|
sig { void }
|
||||||
def keep_but_prune_recursive_deps
|
def keep_but_prune_recursive_deps
|
||||||
throw(:action, :keep_but_prune_recursive_deps)
|
throw(:action, :keep_but_prune_recursive_deps)
|
||||||
@ -282,7 +286,6 @@ class UsesFromMacOSDependency < Dependency
|
|||||||
self.class.new(formula.full_name.to_s, tags, bounds:)
|
self.class.new(formula.full_name.to_s, tags, bounds:)
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def inspect
|
def inspect
|
||||||
"#<#{self.class.name}: #{name.inspect} #{tags.inspect} #{bounds.inspect}>"
|
"#<#{self.class.name}: #{name.inspect} #{tags.inspect} #{bounds.inspect}>"
|
||||||
|
|||||||
@ -7,13 +7,13 @@ require "requirement"
|
|||||||
require "requirements"
|
require "requirements"
|
||||||
require "extend/cachable"
|
require "extend/cachable"
|
||||||
|
|
||||||
## A dependency is a formula that another formula needs to install.
|
# A dependency is a formula that another formula needs to install.
|
||||||
## A requirement is something other than a formula that another formula
|
# A requirement is something other than a formula that another formula
|
||||||
## needs to be present. This includes external language modules,
|
# needs to be present. This includes external language modules,
|
||||||
## command-line tools in the path, or any arbitrary predicate.
|
# command-line tools in the path, or any arbitrary predicate.
|
||||||
##
|
#
|
||||||
## The `depends_on` method in the formula DSL is used to declare
|
# The `depends_on` method in the formula DSL is used to declare
|
||||||
## dependencies and requirements.
|
# dependencies and requirements.
|
||||||
|
|
||||||
# This class is used by `depends_on` in the formula DSL to turn dependency
|
# This class is used by `depends_on` in the formula DSL to turn dependency
|
||||||
# specifications into the proper kinds of dependencies and requirements.
|
# specifications into the proper kinds of dependencies and requirements.
|
||||||
|
|||||||
@ -98,7 +98,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
odie "Could not find #{name}! The formula or version may not have existed." if test_formula.nil?
|
odie "Could not find #{name}! The formula or version may not have existed." if test_formula.nil?
|
||||||
else
|
else
|
||||||
# Search in the root directory of <repo> as well as recursively in all of its subdirectories
|
# Search in the root directory of `repo` as well as recursively in all of its subdirectories.
|
||||||
files = Dir[repo/"{,**/}"].filter_map do |dir|
|
files = Dir[repo/"{,**/}"].filter_map do |dir|
|
||||||
Pathname.glob("#{dir}/#{name}.rb").find(&:file?)
|
Pathname.glob("#{dir}/#{name}.rb").find(&:file?)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -15,7 +15,7 @@ module Homebrew
|
|||||||
|
|
||||||
cmd_args do
|
cmd_args do
|
||||||
description <<~EOS
|
description <<~EOS
|
||||||
Download and publish bottles, and apply the bottle commit from a
|
Download and publish bottles and apply the bottle commit from a
|
||||||
pull request with artifacts generated by GitHub Actions.
|
pull request with artifacts generated by GitHub Actions.
|
||||||
Requires write access to the repository.
|
Requires write access to the repository.
|
||||||
EOS
|
EOS
|
||||||
@ -187,7 +187,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Separates a commit message into subject, body, and trailers.
|
# Separates a commit message into subject, body and trailers.
|
||||||
def separate_commit_message(message)
|
def separate_commit_message(message)
|
||||||
subject = message.lines.first.strip
|
subject = message.lines.first.strip
|
||||||
|
|
||||||
@ -337,7 +337,7 @@ module Homebrew
|
|||||||
new_package = package_file.read
|
new_package = package_file.read
|
||||||
bump_subject = determine_bump_subject(old_package, new_package, package_file, reason:)
|
bump_subject = determine_bump_subject(old_package, new_package, package_file, reason:)
|
||||||
|
|
||||||
# Commit with the new subject, body, and trailers.
|
# Commit with the new subject, body and trailers.
|
||||||
safe_system("git", "-C", git_repo.pathname, "commit", "--quiet",
|
safe_system("git", "-C", git_repo.pathname, "commit", "--quiet",
|
||||||
"-m", bump_subject, "-m", messages.join("\n"), "-m", trailers.join("\n"),
|
"-m", bump_subject, "-m", messages.join("\n"), "-m", trailers.join("\n"),
|
||||||
"--author", original_author, "--date", original_date, "--", file)
|
"--author", original_author, "--date", original_date, "--", file)
|
||||||
|
|||||||
@ -20,16 +20,18 @@ module Homebrew
|
|||||||
def run
|
def run
|
||||||
Homebrew.install_bundler_gems!(groups: ["doc"])
|
Homebrew.install_bundler_gems!(groups: ["doc"])
|
||||||
|
|
||||||
HOMEBREW_LIBRARY_PATH.cd do
|
HOMEBREW_LIBRARY_PATH.cd do |dir|
|
||||||
no_api_args = if args.only_public?
|
no_api_args = if args.only_public?
|
||||||
["--hide-api", "private", "--hide-api", "internal"]
|
["--hide-api", "private", "--hide-api", "internal"]
|
||||||
else
|
else
|
||||||
[]
|
[]
|
||||||
end
|
end
|
||||||
|
|
||||||
system "bundle", "exec", "yard", "doc", "--output", "doc", *no_api_args
|
output_dir = dir/"doc"
|
||||||
|
|
||||||
exec_browser "file://#{HOMEBREW_LIBRARY_PATH}/doc/index.html" if args.open?
|
safe_system "bundle", "exec", "yard", "doc", "--fail-on-warning", *no_api_args, "--output", output_dir
|
||||||
|
|
||||||
|
exec_browser "file://#{output_dir}/index.html" if args.open?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -46,6 +46,8 @@ module Homebrew
|
|||||||
|
|
||||||
(tap.path/"Formula").mkpath
|
(tap.path/"Formula").mkpath
|
||||||
|
|
||||||
|
# FIXME: https://github.com/errata-ai/vale/issues/818
|
||||||
|
# <!-- vale off -->
|
||||||
readme = <<~MARKDOWN
|
readme = <<~MARKDOWN
|
||||||
# #{titleized_user} #{titleized_repo}
|
# #{titleized_user} #{titleized_repo}
|
||||||
|
|
||||||
@ -59,6 +61,7 @@ module Homebrew
|
|||||||
|
|
||||||
`brew help`, `man brew` or check [Homebrew's documentation](https://docs.brew.sh).
|
`brew help`, `man brew` or check [Homebrew's documentation](https://docs.brew.sh).
|
||||||
MARKDOWN
|
MARKDOWN
|
||||||
|
# <!-- vale on -->
|
||||||
write_path(tap, "README.md", readme)
|
write_path(tap, "README.md", readme)
|
||||||
|
|
||||||
actions_main = <<~YAML
|
actions_main = <<~YAML
|
||||||
|
|||||||
@ -22,13 +22,13 @@ module Homebrew
|
|||||||
description: "Include tests that use the GitHub API and tests that use any of the taps for " \
|
description: "Include tests that use the GitHub API and tests that use any of the taps for " \
|
||||||
"official external commands."
|
"official external commands."
|
||||||
switch "--debug",
|
switch "--debug",
|
||||||
description: "Enable debugging using ruby/debug, or surface the standard `odebug` output."
|
description: "Enable debugging using `ruby/debug`, or surface the standard `odebug` output."
|
||||||
switch "--changed",
|
switch "--changed",
|
||||||
description: "Only runs tests on files that were changed from the master branch."
|
description: "Only runs tests on files that were changed from the master branch."
|
||||||
switch "--fail-fast",
|
switch "--fail-fast",
|
||||||
description: "Exit early on the first failing test."
|
description: "Exit early on the first failing test."
|
||||||
flag "--only=",
|
flag "--only=",
|
||||||
description: "Run only <test_script>`_spec.rb`. Appending `:`<line_number> will start at a " \
|
description: "Run only `<test_script>_spec.rb`. Appending `:<line_number>` will start at a " \
|
||||||
"specific line."
|
"specific line."
|
||||||
flag "--profile=",
|
flag "--profile=",
|
||||||
description: "Run the test suite serially to find the <n> slowest tests."
|
description: "Run the test suite serially to find the <n> slowest tests."
|
||||||
@ -145,7 +145,10 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Workaround for:
|
# Workaround for:
|
||||||
|
#
|
||||||
|
# ```
|
||||||
# ruby: no -r allowed while running setuid (SecurityError)
|
# ruby: no -r allowed while running setuid (SecurityError)
|
||||||
|
# ```
|
||||||
Process::UID.change_privilege(Process.euid) if Process.euid != Process.uid
|
Process::UID.change_privilege(Process.euid) if Process.euid != Process.uid
|
||||||
|
|
||||||
if parallel
|
if parallel
|
||||||
|
|||||||
@ -116,7 +116,7 @@ module Homebrew
|
|||||||
# update ENV["PATH"]
|
# update ENV["PATH"]
|
||||||
ENV["PATH"] = PATH.new(ENV.fetch("PATH")).prepend(curdir/"bin").to_s
|
ENV["PATH"] = PATH.new(ENV.fetch("PATH")).prepend(curdir/"bin").to_s
|
||||||
|
|
||||||
# run brew help to install portable-ruby (if needed)
|
# Run `brew help` to install `portable-ruby` (if needed).
|
||||||
quiet_system "brew", "help"
|
quiet_system "brew", "help"
|
||||||
|
|
||||||
# run brew update
|
# run brew update
|
||||||
|
|||||||
@ -221,7 +221,7 @@ module Homebrew
|
|||||||
__check_stray_files "/usr/local/lib", "*.dylib", allow_list, <<~EOS
|
__check_stray_files "/usr/local/lib", "*.dylib", allow_list, <<~EOS
|
||||||
Unbrewed dylibs were found in /usr/local/lib.
|
Unbrewed dylibs were found in /usr/local/lib.
|
||||||
If you didn't put them there on purpose they could cause problems when
|
If you didn't put them there on purpose they could cause problems when
|
||||||
building Homebrew formulae, and may need to be deleted.
|
building Homebrew formulae and may need to be deleted.
|
||||||
|
|
||||||
Unexpected dylibs:
|
Unexpected dylibs:
|
||||||
EOS
|
EOS
|
||||||
@ -246,7 +246,7 @@ module Homebrew
|
|||||||
__check_stray_files "/usr/local/lib", "*.a", allow_list, <<~EOS
|
__check_stray_files "/usr/local/lib", "*.a", allow_list, <<~EOS
|
||||||
Unbrewed static libraries were found in /usr/local/lib.
|
Unbrewed static libraries were found in /usr/local/lib.
|
||||||
If you didn't put them there on purpose they could cause problems when
|
If you didn't put them there on purpose they could cause problems when
|
||||||
building Homebrew formulae, and may need to be deleted.
|
building Homebrew formulae and may need to be deleted.
|
||||||
|
|
||||||
Unexpected static libraries:
|
Unexpected static libraries:
|
||||||
EOS
|
EOS
|
||||||
@ -266,7 +266,7 @@ module Homebrew
|
|||||||
__check_stray_files "/usr/local/lib/pkgconfig", "*.pc", allow_list, <<~EOS
|
__check_stray_files "/usr/local/lib/pkgconfig", "*.pc", allow_list, <<~EOS
|
||||||
Unbrewed '.pc' files were found in /usr/local/lib/pkgconfig.
|
Unbrewed '.pc' files were found in /usr/local/lib/pkgconfig.
|
||||||
If you didn't put them there on purpose they could cause problems when
|
If you didn't put them there on purpose they could cause problems when
|
||||||
building Homebrew formulae, and may need to be deleted.
|
building Homebrew formulae and may need to be deleted.
|
||||||
|
|
||||||
Unexpected '.pc' files:
|
Unexpected '.pc' files:
|
||||||
EOS
|
EOS
|
||||||
@ -287,7 +287,7 @@ module Homebrew
|
|||||||
__check_stray_files "/usr/local/lib", "*.la", allow_list, <<~EOS
|
__check_stray_files "/usr/local/lib", "*.la", allow_list, <<~EOS
|
||||||
Unbrewed '.la' files were found in /usr/local/lib.
|
Unbrewed '.la' files were found in /usr/local/lib.
|
||||||
If you didn't put them there on purpose they could cause problems when
|
If you didn't put them there on purpose they could cause problems when
|
||||||
building Homebrew formulae, and may need to be deleted.
|
building Homebrew formulae and may need to be deleted.
|
||||||
|
|
||||||
Unexpected '.la' files:
|
Unexpected '.la' files:
|
||||||
EOS
|
EOS
|
||||||
@ -306,7 +306,7 @@ module Homebrew
|
|||||||
__check_stray_files "/usr/local/include", "**/*.h", allow_list, <<~EOS
|
__check_stray_files "/usr/local/include", "**/*.h", allow_list, <<~EOS
|
||||||
Unbrewed header files were found in /usr/local/include.
|
Unbrewed header files were found in /usr/local/include.
|
||||||
If you didn't put them there on purpose they could cause problems when
|
If you didn't put them there on purpose they could cause problems when
|
||||||
building Homebrew formulae, and may need to be deleted.
|
building Homebrew formulae and may need to be deleted.
|
||||||
|
|
||||||
Unexpected header files:
|
Unexpected header files:
|
||||||
EOS
|
EOS
|
||||||
@ -491,7 +491,7 @@ module Homebrew
|
|||||||
|
|
||||||
<<~EOS
|
<<~EOS
|
||||||
Git could not be found in your PATH.
|
Git could not be found in your PATH.
|
||||||
Homebrew uses Git for several internal functions, and some formulae use Git
|
Homebrew uses Git for several internal functions and some formulae use Git
|
||||||
checkouts instead of stable tarballs. You may want to install Git:
|
checkouts instead of stable tarballs. You may want to install Git:
|
||||||
brew install git
|
brew install git
|
||||||
EOS
|
EOS
|
||||||
|
|||||||
@ -77,11 +77,9 @@ class AbstractDownloadStrategy
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Disable any output during downloading.
|
# Disable any output during downloading.
|
||||||
#
|
|
||||||
# @deprecated
|
|
||||||
sig { void }
|
sig { void }
|
||||||
def shutup!
|
def shutup!
|
||||||
odeprecated "AbstractDownloadStrategy#shutup!", "AbstractDownloadStrategy#quiet!"
|
odeprecated "`AbstractDownloadStrategy#shutup!`", "`AbstractDownloadStrategy#quiet!`"
|
||||||
quiet!
|
quiet!
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -125,7 +123,6 @@ class AbstractDownloadStrategy
|
|||||||
end
|
end
|
||||||
private :chdir
|
private :chdir
|
||||||
|
|
||||||
# @!attribute [r] source_modified_time
|
|
||||||
# Returns the most recent modified time for all files in the current working directory after stage.
|
# Returns the most recent modified time for all files in the current working directory after stage.
|
||||||
#
|
#
|
||||||
# @api public
|
# @api public
|
||||||
@ -236,9 +233,7 @@ class VCSDownloadStrategy < AbstractDownloadStrategy
|
|||||||
version.respond_to?(:head?) && version.head?
|
version.respond_to?(:head?) && version.head?
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!attribute [r] last_commit
|
# Return the most recent modified timestamp.
|
||||||
# Return last commit's unique identifier for the repository.
|
|
||||||
# Return most recent modified timestamp unless overridden.
|
|
||||||
#
|
#
|
||||||
# @api public
|
# @api public
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
@ -733,7 +728,8 @@ class SubversionDownloadStrategy < VCSDownloadStrategy
|
|||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
# @see AbstractDownloadStrategy#source_modified_time
|
# Returns the most recent modified time for all files in the current working directory after stage.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
sig { returns(Time) }
|
sig { returns(Time) }
|
||||||
def source_modified_time
|
def source_modified_time
|
||||||
@ -747,7 +743,8 @@ class SubversionDownloadStrategy < VCSDownloadStrategy
|
|||||||
Time.parse time
|
Time.parse time
|
||||||
end
|
end
|
||||||
|
|
||||||
# @see VCSDownloadStrategy#last_commit
|
# Return last commit's unique identifier for the repository.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def last_commit
|
def last_commit
|
||||||
@ -847,7 +844,8 @@ class GitDownloadStrategy < VCSDownloadStrategy
|
|||||||
@ref ||= "master"
|
@ref ||= "master"
|
||||||
end
|
end
|
||||||
|
|
||||||
# @see AbstractDownloadStrategy#source_modified_time
|
# Returns the most recent modified time for all files in the current working directory after stage.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
sig { returns(Time) }
|
sig { returns(Time) }
|
||||||
def source_modified_time
|
def source_modified_time
|
||||||
@ -855,7 +853,8 @@ class GitDownloadStrategy < VCSDownloadStrategy
|
|||||||
Time.parse(out)
|
Time.parse(out)
|
||||||
end
|
end
|
||||||
|
|
||||||
# @see VCSDownloadStrategy#last_commit
|
# Return last commit's unique identifier for the repository.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def last_commit
|
def last_commit
|
||||||
@ -932,8 +931,8 @@ class GitDownloadStrategy < VCSDownloadStrategy
|
|||||||
|
|
||||||
args << "--no-checkout" << "--filter=blob:none" if partial_clone_sparse_checkout?
|
args << "--no-checkout" << "--filter=blob:none" if partial_clone_sparse_checkout?
|
||||||
|
|
||||||
args << "--config" << "advice.detachedHead=false" # silences detached head warning
|
args << "--config" << "advice.detachedHead=false" # Silences “detached head” warning.
|
||||||
args << "--config" << "core.fsmonitor=false" # prevent fsmonitor from watching this repo
|
args << "--config" << "core.fsmonitor=false" # Prevent `fsmonitor` from watching this repository.
|
||||||
args << @url << cached_location.to_s
|
args << @url << cached_location.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1165,7 +1164,8 @@ class CVSDownloadStrategy < VCSDownloadStrategy
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# @see AbstractDownloadStrategy#source_modified_time
|
# Returns the most recent modified time for all files in the current working directory after stage.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
sig { returns(Time) }
|
sig { returns(Time) }
|
||||||
def source_modified_time
|
def source_modified_time
|
||||||
@ -1240,7 +1240,8 @@ class MercurialDownloadStrategy < VCSDownloadStrategy
|
|||||||
@url = @url.sub(%r{^hg://}, "")
|
@url = @url.sub(%r{^hg://}, "")
|
||||||
end
|
end
|
||||||
|
|
||||||
# @see AbstractDownloadStrategy#source_modified_time
|
# Returns the most recent modified time for all files in the current working directory after stage.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
sig { returns(Time) }
|
sig { returns(Time) }
|
||||||
def source_modified_time
|
def source_modified_time
|
||||||
@ -1250,7 +1251,8 @@ class MercurialDownloadStrategy < VCSDownloadStrategy
|
|||||||
Time.parse(out)
|
Time.parse(out)
|
||||||
end
|
end
|
||||||
|
|
||||||
# @see VCSDownloadStrategy#last_commit
|
# Return last commit's unique identifier for the repository.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def last_commit
|
def last_commit
|
||||||
@ -1327,7 +1329,8 @@ class BazaarDownloadStrategy < VCSDownloadStrategy
|
|||||||
@url = @url.sub(%r{^bzr://}, "")
|
@url = @url.sub(%r{^bzr://}, "")
|
||||||
end
|
end
|
||||||
|
|
||||||
# @see AbstractDownloadStrategy#source_modified_time
|
# Returns the most recent modified time for all files in the current working directory after stage.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
sig { returns(Time) }
|
sig { returns(Time) }
|
||||||
def source_modified_time
|
def source_modified_time
|
||||||
@ -1338,7 +1341,8 @@ class BazaarDownloadStrategy < VCSDownloadStrategy
|
|||||||
Time.parse(timestamp)
|
Time.parse(timestamp)
|
||||||
end
|
end
|
||||||
|
|
||||||
# @see VCSDownloadStrategy#last_commit
|
# Return last commit's unique identifier for the repository.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def last_commit
|
def last_commit
|
||||||
@ -1390,7 +1394,8 @@ class FossilDownloadStrategy < VCSDownloadStrategy
|
|||||||
@url = @url.sub(%r{^fossil://}, "")
|
@url = @url.sub(%r{^fossil://}, "")
|
||||||
end
|
end
|
||||||
|
|
||||||
# @see AbstractDownloadStrategy#source_modified_time
|
# Returns the most recent modified time for all files in the current working directory after stage.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
sig { returns(Time) }
|
sig { returns(Time) }
|
||||||
def source_modified_time
|
def source_modified_time
|
||||||
@ -1398,7 +1403,8 @@ class FossilDownloadStrategy < VCSDownloadStrategy
|
|||||||
Time.parse(out[/^uuid: +\h+ (.+)$/, 1])
|
Time.parse(out[/^uuid: +\h+ (.+)$/, 1])
|
||||||
end
|
end
|
||||||
|
|
||||||
# @see VCSDownloadStrategy#last_commit
|
# Return last commit's unique identifier for the repository.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def last_commit
|
def last_commit
|
||||||
|
|||||||
@ -16,7 +16,6 @@ class UsageError < RuntimeError
|
|||||||
@reason = reason
|
@reason = reason
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
s = "Invalid usage"
|
s = "Invalid usage"
|
||||||
@ -109,7 +108,6 @@ class FormulaOrCaskUnavailableError < RuntimeError
|
|||||||
"Did you mean #{similar_formula_names.to_sentence two_words_connector: " or ", last_word_connector: " or "}?"
|
"Did you mean #{similar_formula_names.to_sentence two_words_connector: " or ", last_word_connector: " or "}?"
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
s = "No available formula or cask with the name \"#{name}\". #{did_you_mean}".strip
|
s = "No available formula or cask with the name \"#{name}\". #{did_you_mean}".strip
|
||||||
@ -129,7 +127,6 @@ class TapFormulaOrCaskUnavailableError < FormulaOrCaskUnavailableError
|
|||||||
@tap = tap
|
@tap = tap
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
s = super
|
s = super
|
||||||
@ -149,7 +146,6 @@ class FormulaUnavailableError < FormulaOrCaskUnavailableError
|
|||||||
" (dependency of #{dependent})" if dependent && dependent != name
|
" (dependency of #{dependent})" if dependent && dependent != name
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
"No available formula with the name \"#{name}\"#{dependent_s}. #{did_you_mean}".strip
|
"No available formula with the name \"#{name}\"#{dependent_s}. #{did_you_mean}".strip
|
||||||
@ -160,7 +156,6 @@ end
|
|||||||
module FormulaClassUnavailableErrorModule
|
module FormulaClassUnavailableErrorModule
|
||||||
attr_reader :path, :class_name, :class_list
|
attr_reader :path, :class_name, :class_list
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
s = super
|
s = super
|
||||||
@ -204,7 +199,6 @@ end
|
|||||||
module FormulaUnreadableErrorModule
|
module FormulaUnreadableErrorModule
|
||||||
attr_reader :formula_error
|
attr_reader :formula_error
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
"#{name}: " + formula_error.to_s
|
"#{name}: " + formula_error.to_s
|
||||||
@ -233,7 +227,6 @@ class TapFormulaUnavailableError < FormulaUnavailableError
|
|||||||
super "#{tap}/#{name}"
|
super "#{tap}/#{name}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
s = super
|
s = super
|
||||||
@ -572,7 +565,7 @@ class UnbottledError < RuntimeError
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Raised by Homebrew.install, Homebrew.reinstall, and Homebrew.upgrade
|
# Raised by `Homebrew.install`, `Homebrew.reinstall` and `Homebrew.upgrade`
|
||||||
# if the user passes any flags/environment that would case a bottle-only
|
# if the user passes any flags/environment that would case a bottle-only
|
||||||
# installation on a system without build tools to fail.
|
# installation on a system without build tools to fail.
|
||||||
class BuildFlagsError < RuntimeError
|
class BuildFlagsError < RuntimeError
|
||||||
|
|||||||
@ -17,10 +17,16 @@ module Kernel
|
|||||||
private :superenv?
|
private :superenv?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# <!-- vale off -->
|
||||||
# @!parse
|
# @!parse
|
||||||
# # ENV is not actually a class, but this makes `YARD` happy
|
# # `ENV` is not actually a class, but this makes YARD happy
|
||||||
# # @see https://rubydoc.info/stdlib/core/ENV ENV core documentation
|
# # @see https://rubydoc.info/stdlib/core/ENV
|
||||||
# class ENV; end
|
# # <code>ENV</code> core documentation
|
||||||
|
# # @see Superenv
|
||||||
|
# # @see Stdenv
|
||||||
|
# class ENV; end
|
||||||
|
# <!-- vale on -->
|
||||||
|
|
||||||
module EnvActivation
|
module EnvActivation
|
||||||
sig { params(env: T.nilable(String)).void }
|
sig { params(env: T.nilable(String)).void }
|
||||||
def activate_extensions!(env: nil)
|
def activate_extensions!(env: nil)
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
# typed: strict
|
# typed: strict
|
||||||
|
|
||||||
|
# @!visibility private
|
||||||
module EnvMethods
|
module EnvMethods
|
||||||
include Kernel
|
include Kernel
|
||||||
|
|
||||||
@ -39,6 +40,7 @@ module EnvActivation
|
|||||||
include Superenv
|
include Superenv
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @!visibility private
|
||||||
class Sorbet
|
class Sorbet
|
||||||
module Private
|
module Private
|
||||||
module Static
|
module Static
|
||||||
|
|||||||
@ -4,6 +4,7 @@ module SharedEnvExtension
|
|||||||
include EnvMethods
|
include EnvMethods
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @!visibility private
|
||||||
class Sorbet
|
class Sorbet
|
||||||
module Private
|
module Private
|
||||||
module Static
|
module Static
|
||||||
|
|||||||
@ -2,59 +2,72 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Array
|
class Array
|
||||||
# Equal to <tt>self[1]</tt>.
|
# Equal to `self[1]`.
|
||||||
#
|
#
|
||||||
# %w( a b c d e ).second # => "b"
|
# ### Example
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
|
# %w( a b c d e ).second # => "b"
|
||||||
|
# ```
|
||||||
def second = self[1]
|
def second = self[1]
|
||||||
|
|
||||||
# Equal to <tt>self[2]</tt>.
|
# Equal to `self[2]`.
|
||||||
#
|
#
|
||||||
# %w( a b c d e ).third # => "c"
|
# ### Example
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
|
# %w( a b c d e ).third # => "c"
|
||||||
|
# ```
|
||||||
def third = self[2]
|
def third = self[2]
|
||||||
|
|
||||||
# Equal to <tt>self[3]</tt>.
|
# Equal to `self[3]`.
|
||||||
#
|
#
|
||||||
# %w( a b c d e ).fourth # => "d"
|
# ### Example
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
|
# %w( a b c d e ).fourth # => "d"
|
||||||
|
# ```
|
||||||
def fourth = self[3]
|
def fourth = self[3]
|
||||||
|
|
||||||
# Equal to <tt>self[4]</tt>.
|
# Equal to `self[4]`.
|
||||||
#
|
#
|
||||||
# %w( a b c d e ).fifth # => "e"
|
# ### Example
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
|
# %w( a b c d e ).fifth # => "e"
|
||||||
|
# ```
|
||||||
def fifth = self[4]
|
def fifth = self[4]
|
||||||
|
|
||||||
# Converts the array to a comma-separated sentence where the last element is
|
# Converts the array to a comma-separated sentence where the last element is
|
||||||
# joined by the connector word.
|
# joined by the connector word.
|
||||||
#
|
#
|
||||||
# You can pass the following kwargs to change the default behavior:
|
# ### Examples
|
||||||
#
|
#
|
||||||
# * <tt>:words_connector</tt> - The sign or word used to join all but the last
|
# ```ruby
|
||||||
# element in arrays with three or more elements (default: ", ").
|
# [].to_sentence # => ""
|
||||||
# * <tt>:last_word_connector</tt> - The sign or word used to join the last element
|
# ['one'].to_sentence # => "one"
|
||||||
# in arrays with three or more elements (default: ", and ").
|
# ['one', 'two'].to_sentence # => "one and two"
|
||||||
# * <tt>:two_words_connector</tt> - The sign or word used to join the elements
|
# ['one', 'two', 'three'].to_sentence # => "one, two and three"
|
||||||
# in arrays with two elements (default: " and ").
|
# ['one', 'two'].to_sentence(two_words_connector: '-')
|
||||||
|
# # => "one-two"
|
||||||
|
# ```
|
||||||
#
|
#
|
||||||
# ==== Examples
|
# ```
|
||||||
|
# ['one', 'two', 'three'].to_sentence(words_connector: ' or ', last_word_connector: ' or at least ')
|
||||||
|
# # => "one or two or at least three"
|
||||||
|
# ```
|
||||||
#
|
#
|
||||||
# [].to_sentence # => ""
|
|
||||||
# ['one'].to_sentence # => "one"
|
|
||||||
# ['one', 'two'].to_sentence # => "one and two"
|
|
||||||
# ['one', 'two', 'three'].to_sentence # => "one, two, and three"
|
|
||||||
# ['one', 'two'].to_sentence(two_words_connector: '-')
|
|
||||||
# # => "one-two"
|
|
||||||
#
|
|
||||||
# ['one', 'two', 'three'].to_sentence(words_connector: ' or ', last_word_connector: ' or at least ')
|
|
||||||
# # => "one or two or at least three"
|
|
||||||
# @see https://github.com/rails/rails/blob/v7.0.4.2/activesupport/lib/active_support/core_ext/array/conversions.rb#L8-L84
|
# @see https://github.com/rails/rails/blob/v7.0.4.2/activesupport/lib/active_support/core_ext/array/conversions.rb#L8-L84
|
||||||
# ActiveSupport Array#to_sentence monkey-patch
|
# ActiveSupport Array#to_sentence monkey-patch
|
||||||
#
|
#
|
||||||
|
#
|
||||||
# Copyright (c) David Heinemeier Hansson
|
# Copyright (c) David Heinemeier Hansson
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
# "Software"), to deal in the Software without restriction, including
|
# "Software"), to deal in the Software without restriction, including
|
||||||
# without limitation the rights to use, copy, modify, merge, publish,
|
# without limitation the rights to use, copy, modify, merge, publish,
|
||||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
# distribute, sublicense and/or sell copies of the Software and to
|
||||||
# permit persons to whom the Software is furnished to do so, subject to
|
# permit persons to whom the Software is furnished to do so, subject to
|
||||||
# the following conditions:
|
# the following conditions:
|
||||||
#
|
#
|
||||||
@ -68,6 +81,14 @@ class Array
|
|||||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# @param [String] words_connector The sign or word used to join all but the last
|
||||||
|
# element in arrays with three or more elements (default: `", "`).
|
||||||
|
# @param [String] last_word_connector The sign or word used to join the last element
|
||||||
|
# in arrays with three or more elements (default: `" and "`).
|
||||||
|
# @param [String] two_words_connector The sign or word used to join the elements
|
||||||
|
# in arrays with two elements (default: `" and "`).
|
||||||
sig { params(words_connector: String, two_words_connector: String, last_word_connector: String).returns(String) }
|
sig { params(words_connector: String, two_words_connector: String, last_word_connector: String).returns(String) }
|
||||||
def to_sentence(words_connector: ", ", two_words_connector: " and ", last_word_connector: " and ")
|
def to_sentence(words_connector: ", ", two_words_connector: " and ", last_word_connector: " and ")
|
||||||
case length
|
case length
|
||||||
|
|||||||
@ -3,15 +3,20 @@
|
|||||||
|
|
||||||
class Object
|
class Object
|
||||||
# An object is blank if it's false, empty, or a whitespace string.
|
# An object is blank if it's false, empty, or a whitespace string.
|
||||||
# For example, +nil+, '', ' ', [], {}, and +false+ are all blank.
|
|
||||||
#
|
#
|
||||||
# This simplifies
|
# For example, `nil`, `''`, `' '`, `[]`, `{}` and `false` are all blank.
|
||||||
#
|
#
|
||||||
# !address || address.empty?
|
# ### Example
|
||||||
#
|
#
|
||||||
# to
|
# ```ruby
|
||||||
|
# !address || address.empty?
|
||||||
|
# ```
|
||||||
#
|
#
|
||||||
# address.blank?
|
# can be simplified to
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
|
# address.blank?
|
||||||
|
# ```
|
||||||
sig { returns(T::Boolean) }
|
sig { returns(T::Boolean) }
|
||||||
def blank?
|
def blank?
|
||||||
respond_to?(:empty?) ? !!T.unsafe(self).empty? : false
|
respond_to?(:empty?) ? !!T.unsafe(self).empty? : false
|
||||||
@ -21,20 +26,23 @@ class Object
|
|||||||
sig { returns(T::Boolean) }
|
sig { returns(T::Boolean) }
|
||||||
def present? = !blank?
|
def present? = !blank?
|
||||||
|
|
||||||
# Returns the receiver if it's present otherwise returns +nil+.
|
# Returns the receiver if it's present, otherwise returns `nil`.
|
||||||
# <tt>object.presence</tt> is equivalent to
|
|
||||||
#
|
#
|
||||||
# object.present? ? object : nil
|
# `object.presence` is equivalent to `object.present? ? object : nil`.
|
||||||
#
|
#
|
||||||
# For example, something like
|
# ### Example
|
||||||
#
|
#
|
||||||
# state = params[:state] if params[:state].present?
|
# ```ruby
|
||||||
# country = params[:country] if params[:country].present?
|
# state = params[:state] if params[:state].present?
|
||||||
# region = state || country || 'US'
|
# country = params[:country] if params[:country].present?
|
||||||
|
# region = state || country || 'US'
|
||||||
|
# ```
|
||||||
#
|
#
|
||||||
# becomes
|
# can be simplified to
|
||||||
#
|
#
|
||||||
# region = params[:state].presence || params[:country].presence || 'US'
|
# ```ruby
|
||||||
|
# region = params[:state].presence || params[:country].presence || 'US'
|
||||||
|
# ```
|
||||||
sig { returns(T.nilable(T.self_type)) }
|
sig { returns(T.nilable(T.self_type)) }
|
||||||
def presence
|
def presence
|
||||||
self if present?
|
self if present?
|
||||||
@ -42,9 +50,11 @@ class Object
|
|||||||
end
|
end
|
||||||
|
|
||||||
class NilClass
|
class NilClass
|
||||||
# +nil+ is blank:
|
# `nil` is blank:
|
||||||
#
|
#
|
||||||
# nil.blank? # => true
|
# ```ruby
|
||||||
|
# nil.blank? # => true
|
||||||
|
# ```
|
||||||
sig { returns(TrueClass) }
|
sig { returns(TrueClass) }
|
||||||
def blank? = true
|
def blank? = true
|
||||||
|
|
||||||
@ -53,9 +63,11 @@ class NilClass
|
|||||||
end
|
end
|
||||||
|
|
||||||
class FalseClass
|
class FalseClass
|
||||||
# +false+ is blank:
|
# `false` is blank:
|
||||||
#
|
#
|
||||||
# false.blank? # => true
|
# ```ruby
|
||||||
|
# false.blank? # => true
|
||||||
|
# ```
|
||||||
sig { returns(TrueClass) }
|
sig { returns(TrueClass) }
|
||||||
def blank? = true
|
def blank? = true
|
||||||
|
|
||||||
@ -64,9 +76,11 @@ class FalseClass
|
|||||||
end
|
end
|
||||||
|
|
||||||
class TrueClass
|
class TrueClass
|
||||||
# +true+ is not blank:
|
# `true` is not blank:
|
||||||
#
|
#
|
||||||
# true.blank? # => false
|
# ```ruby
|
||||||
|
# true.blank? # => false
|
||||||
|
# ```
|
||||||
sig { returns(FalseClass) }
|
sig { returns(FalseClass) }
|
||||||
def blank? = false
|
def blank? = false
|
||||||
|
|
||||||
@ -77,11 +91,12 @@ end
|
|||||||
class Array
|
class Array
|
||||||
# An array is blank if it's empty:
|
# An array is blank if it's empty:
|
||||||
#
|
#
|
||||||
# [].blank? # => true
|
# ```ruby
|
||||||
# [1,2,3].blank? # => false
|
# [].blank? # => true
|
||||||
#
|
# [1,2,3].blank? # => false
|
||||||
# @return [true, false]
|
# ```
|
||||||
alias blank? empty?
|
sig { returns(T::Boolean) }
|
||||||
|
def blank? = empty?
|
||||||
|
|
||||||
sig { returns(T::Boolean) }
|
sig { returns(T::Boolean) }
|
||||||
def present? = !empty? # :nodoc:
|
def present? = !empty? # :nodoc:
|
||||||
@ -90,11 +105,13 @@ end
|
|||||||
class Hash
|
class Hash
|
||||||
# A hash is blank if it's empty:
|
# A hash is blank if it's empty:
|
||||||
#
|
#
|
||||||
# {}.blank? # => true
|
|
||||||
# { key: 'value' }.blank? # => false
|
|
||||||
#
|
#
|
||||||
# @return [true, false]
|
# ```ruby
|
||||||
alias blank? empty?
|
# {}.blank? # => true
|
||||||
|
# { key: 'value' }.blank? # => false
|
||||||
|
# ```
|
||||||
|
sig { returns(T::Boolean) }
|
||||||
|
def blank? = empty?
|
||||||
|
|
||||||
sig { returns(T::Boolean) }
|
sig { returns(T::Boolean) }
|
||||||
def present? = !empty? # :nodoc:
|
def present? = !empty? # :nodoc:
|
||||||
@ -103,9 +120,12 @@ end
|
|||||||
class Symbol
|
class Symbol
|
||||||
# A Symbol is blank if it's empty:
|
# A Symbol is blank if it's empty:
|
||||||
#
|
#
|
||||||
# :''.blank? # => true
|
# ```ruby
|
||||||
# :symbol.blank? # => false
|
# :''.blank? # => true
|
||||||
alias blank? empty?
|
# :symbol.blank? # => false
|
||||||
|
# ```
|
||||||
|
sig { returns(T::Boolean) }
|
||||||
|
def blank? = empty?
|
||||||
|
|
||||||
sig { returns(T::Boolean) }
|
sig { returns(T::Boolean) }
|
||||||
def present? = !empty? # :nodoc:
|
def present? = !empty? # :nodoc:
|
||||||
@ -122,14 +142,18 @@ class String
|
|||||||
|
|
||||||
# A string is blank if it's empty or contains whitespaces only:
|
# A string is blank if it's empty or contains whitespaces only:
|
||||||
#
|
#
|
||||||
# ''.blank? # => true
|
# ```ruby
|
||||||
# ' '.blank? # => true
|
# ''.blank? # => true
|
||||||
# "\t\n\r".blank? # => true
|
# ' '.blank? # => true
|
||||||
# ' blah '.blank? # => false
|
# "\t\n\r".blank? # => true
|
||||||
|
# ' blah '.blank? # => false
|
||||||
|
# ```
|
||||||
#
|
#
|
||||||
# Unicode whitespace is supported:
|
# Unicode whitespace is supported:
|
||||||
#
|
#
|
||||||
# "\u00a0".blank? # => true
|
# ```ruby
|
||||||
|
# "\u00a0".blank? # => true
|
||||||
|
# ```
|
||||||
sig { returns(T::Boolean) }
|
sig { returns(T::Boolean) }
|
||||||
def blank?
|
def blank?
|
||||||
# The regexp that matches blank strings is expensive. For the case of empty
|
# The regexp that matches blank strings is expensive. For the case of empty
|
||||||
@ -150,8 +174,10 @@ end
|
|||||||
class Numeric # :nodoc:
|
class Numeric # :nodoc:
|
||||||
# No number is blank:
|
# No number is blank:
|
||||||
#
|
#
|
||||||
# 1.blank? # => false
|
# ```ruby
|
||||||
# 0.blank? # => false
|
# 1.blank? # => false
|
||||||
|
# 0.blank? # => false
|
||||||
|
# ```
|
||||||
sig { returns(FalseClass) }
|
sig { returns(FalseClass) }
|
||||||
def blank? = false
|
def blank? = false
|
||||||
|
|
||||||
@ -162,7 +188,9 @@ end
|
|||||||
class Time # :nodoc:
|
class Time # :nodoc:
|
||||||
# No Time is blank:
|
# No Time is blank:
|
||||||
#
|
#
|
||||||
# Time.now.blank? # => false
|
# ```ruby
|
||||||
|
# Time.now.blank? # => false
|
||||||
|
# ```
|
||||||
sig { returns(FalseClass) }
|
sig { returns(FalseClass) }
|
||||||
def blank? = false
|
def blank? = false
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Enumerable
|
module Enumerable
|
||||||
# The negative of the <tt>Enumerable#include?</tt>. Returns +true+ if the
|
# The negative of the {Enumerable#include?}. Returns `true` if the
|
||||||
# collection does not include the object.
|
# collection does not include the object.
|
||||||
sig { params(object: T.untyped).returns(T::Boolean) }
|
sig { params(object: T.untyped).returns(T::Boolean) }
|
||||||
def exclude?(object) = !include?(object)
|
def exclude?(object) = !include?(object)
|
||||||
@ -10,21 +10,29 @@ module Enumerable
|
|||||||
# Returns a new +Array+ without the blank items.
|
# Returns a new +Array+ without the blank items.
|
||||||
# Uses Object#blank? for determining if an item is blank.
|
# Uses Object#blank? for determining if an item is blank.
|
||||||
#
|
#
|
||||||
# [1, "", nil, 2, " ", [], {}, false, true].compact_blank
|
# ### Examples
|
||||||
# # => [1, 2, true]
|
|
||||||
#
|
#
|
||||||
# Set.new([nil, "", 1, false]).compact_blank
|
# ```
|
||||||
# # => [1]
|
# [1, "", nil, 2, " ", [], {}, false, true].compact_blank
|
||||||
|
# # => [1, 2, true]
|
||||||
|
# ```
|
||||||
#
|
#
|
||||||
# When called on a +Hash+, returns a new +Hash+ without the blank values.
|
# ```ruby
|
||||||
|
# Set.new([nil, "", 1, false]).compact_blank
|
||||||
|
# # => [1]
|
||||||
|
# ```
|
||||||
#
|
#
|
||||||
# { a: "", b: 1, c: nil, d: [], e: false, f: true }.compact_blank
|
# When called on a {Hash}, returns a new {Hash} without the blank values.
|
||||||
# # => { b: 1, f: true }
|
#
|
||||||
|
# ```ruby
|
||||||
|
# { a: "", b: 1, c: nil, d: [], e: false, f: true }.compact_blank
|
||||||
|
# # => { b: 1, f: true }
|
||||||
|
# ```
|
||||||
sig { returns(T.self_type) }
|
sig { returns(T.self_type) }
|
||||||
def compact_blank = T.unsafe(self).reject(&:blank?)
|
def compact_blank = T.unsafe(self).reject(&:blank?)
|
||||||
end
|
end
|
||||||
|
|
||||||
class Hash
|
class Hash
|
||||||
# Hash#reject has its own definition, so this needs one too.
|
# {Hash#reject} has its own definition, so this needs one too.
|
||||||
def compact_blank = reject { |_k, v| T.unsafe(v).blank? }
|
def compact_blank = reject { |_k, v| T.unsafe(v).blank? }
|
||||||
end
|
end
|
||||||
|
|||||||
@ -2,25 +2,31 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Hash
|
class Hash
|
||||||
# Returns a new hash with +self+ and +other_hash+ merged recursively.
|
# Returns a new hash with `self` and `other_hash` merged recursively.
|
||||||
#
|
#
|
||||||
# h1 = { a: true, b: { c: [1, 2, 3] } }
|
# ### Examples
|
||||||
# h2 = { a: false, b: { x: [3, 4, 5] } }
|
|
||||||
#
|
#
|
||||||
# h1.deep_merge(h2) # => { a: false, b: { c: [1, 2, 3], x: [3, 4, 5] } }
|
# ```ruby
|
||||||
|
# h1 = { a: true, b: { c: [1, 2, 3] } }
|
||||||
|
# h2 = { a: false, b: { x: [3, 4, 5] } }
|
||||||
|
#
|
||||||
|
# h1.deep_merge(h2) # => { a: false, b: { c: [1, 2, 3], x: [3, 4, 5] } }
|
||||||
|
# ```
|
||||||
#
|
#
|
||||||
# Like with Hash#merge in the standard library, a block can be provided
|
# Like with Hash#merge in the standard library, a block can be provided
|
||||||
# to merge values:
|
# to merge values:
|
||||||
#
|
#
|
||||||
# h1 = { a: 100, b: 200, c: { c1: 100 } }
|
# ```ruby
|
||||||
# h2 = { b: 250, c: { c1: 200 } }
|
# h1 = { a: 100, b: 200, c: { c1: 100 } }
|
||||||
# h1.deep_merge(h2) { |key, this_val, other_val| this_val + other_val }
|
# h2 = { b: 250, c: { c1: 200 } }
|
||||||
# # => { a: 100, b: 450, c: { c1: 300 } }
|
# h1.deep_merge(h2) { |key, this_val, other_val| this_val + other_val }
|
||||||
|
# # => { a: 100, b: 450, c: { c1: 300 } }
|
||||||
|
# ```
|
||||||
def deep_merge(other_hash, &block)
|
def deep_merge(other_hash, &block)
|
||||||
dup.deep_merge!(other_hash, &block)
|
dup.deep_merge!(other_hash, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Same as +deep_merge+, but modifies +self+.
|
# Same as {#deep_merge}, but modifies `self`.
|
||||||
def deep_merge!(other_hash, &block)
|
def deep_merge!(other_hash, &block)
|
||||||
merge!(other_hash) do |key, this_val, other_val|
|
merge!(other_hash) do |key, this_val, other_val|
|
||||||
if T.unsafe(this_val).is_a?(Hash) && other_val.is_a?(Hash)
|
if T.unsafe(this_val).is_a?(Hash) && other_val.is_a?(Hash)
|
||||||
|
|||||||
@ -6,11 +6,14 @@ class Hash
|
|||||||
# This includes the values from the root hash and from all
|
# This includes the values from the root hash and from all
|
||||||
# nested hashes and arrays.
|
# nested hashes and arrays.
|
||||||
#
|
#
|
||||||
# @example
|
# ### Example
|
||||||
# hash = { person: { name: 'Rob', age: '28' } }
|
|
||||||
#
|
#
|
||||||
# hash.deep_transform_values{ |value| value.to_s.upcase }
|
# ```ruby
|
||||||
# # => {person: {name: "ROB", age: "28"}}
|
# hash = { person: { name: 'Rob', age: '28' } }
|
||||||
|
#
|
||||||
|
# hash.deep_transform_values{ |value| value.to_s.upcase }
|
||||||
|
# # => {person: {name: "ROB", age: "28"}}
|
||||||
|
# ```
|
||||||
def deep_transform_values(&block) = _deep_transform_values_in_object(self, &block)
|
def deep_transform_values(&block) = _deep_transform_values_in_object(self, &block)
|
||||||
|
|
||||||
# Destructively converts all values by using the block operation.
|
# Destructively converts all values by using the block operation.
|
||||||
|
|||||||
@ -5,14 +5,18 @@ class Hash
|
|||||||
# Validates all keys in a hash match `*valid_keys`, raising
|
# Validates all keys in a hash match `*valid_keys`, raising
|
||||||
# `ArgumentError` on a mismatch.
|
# `ArgumentError` on a mismatch.
|
||||||
#
|
#
|
||||||
# Note that keys are treated differently than HashWithIndifferentAccess,
|
# Note that keys are treated differently than `HashWithIndifferentAccess`,
|
||||||
# meaning that string and symbol keys will not match.
|
# meaning that string and symbol keys will not match.
|
||||||
#
|
#
|
||||||
# { name: 'Rob', years: '28' }.assert_valid_keys(:name, :age)
|
# ### Example#
|
||||||
# # => raises "ArgumentError: Unknown key: :years. Valid keys are: :name, :age"
|
#
|
||||||
# { name: 'Rob', age: '28' }.assert_valid_keys('name', 'age')
|
# ```ruby
|
||||||
# # => raises "ArgumentError: Unknown key: :name. Valid keys are: 'name', 'age'"
|
# { name: 'Rob', years: '28' }.assert_valid_keys(:name, :age)
|
||||||
# { name: 'Rob', age: '28' }.assert_valid_keys(:name, :age) # => passes, raises nothing
|
# # => raises "ArgumentError: Unknown key: :years. Valid keys are: :name, :age"
|
||||||
|
# { name: 'Rob', age: '28' }.assert_valid_keys('name', 'age')
|
||||||
|
# # => raises "ArgumentError: Unknown key: :name. Valid keys are: 'name', 'age'"
|
||||||
|
# { name: 'Rob', age: '28' }.assert_valid_keys(:name, :age) # => passes, raises nothing
|
||||||
|
# ```
|
||||||
sig { params(valid_keys: T.untyped).void }
|
sig { params(valid_keys: T.untyped).void }
|
||||||
def assert_valid_keys(*valid_keys)
|
def assert_valid_keys(*valid_keys)
|
||||||
valid_keys.flatten!
|
valid_keys.flatten!
|
||||||
@ -28,10 +32,14 @@ class Hash
|
|||||||
# This includes the keys from the root hash and from all
|
# This includes the keys from the root hash and from all
|
||||||
# nested hashes and arrays.
|
# nested hashes and arrays.
|
||||||
#
|
#
|
||||||
# hash = { person: { name: 'Rob', age: '28' } }
|
# ### Example
|
||||||
#
|
#
|
||||||
# hash.deep_transform_keys{ |key| key.to_s.upcase }
|
# ```ruby
|
||||||
# # => {"PERSON"=>{"NAME"=>"Rob", "AGE"=>"28"}}
|
# hash = { person: { name: 'Rob', age: '28' } }
|
||||||
|
#
|
||||||
|
# hash.deep_transform_keys{ |key| key.to_s.upcase }
|
||||||
|
# # => {"PERSON"=>{"NAME"=>"Rob", "AGE"=>"28"}}
|
||||||
|
# ```
|
||||||
def deep_transform_keys(&block) = _deep_transform_keys_in_object(self, &block)
|
def deep_transform_keys(&block) = _deep_transform_keys_in_object(self, &block)
|
||||||
|
|
||||||
# Destructively converts all keys by using the block operation.
|
# Destructively converts all keys by using the block operation.
|
||||||
@ -43,10 +51,14 @@ class Hash
|
|||||||
# This includes the keys from the root hash and from all
|
# This includes the keys from the root hash and from all
|
||||||
# nested hashes and arrays.
|
# nested hashes and arrays.
|
||||||
#
|
#
|
||||||
# hash = { person: { name: 'Rob', age: '28' } }
|
# ### Example
|
||||||
#
|
#
|
||||||
# hash.deep_stringify_keys
|
# ```ruby
|
||||||
# # => {"person"=>{"name"=>"Rob", "age"=>"28"}}
|
# hash = { person: { name: 'Rob', age: '28' } }
|
||||||
|
#
|
||||||
|
# hash.deep_stringify_keys
|
||||||
|
# # => {"person"=>{"name"=>"Rob", "age"=>"28"}}
|
||||||
|
# ```
|
||||||
def deep_stringify_keys = T.unsafe(self).deep_transform_keys(&:to_s)
|
def deep_stringify_keys = T.unsafe(self).deep_transform_keys(&:to_s)
|
||||||
|
|
||||||
# Destructively converts all keys to strings.
|
# Destructively converts all keys to strings.
|
||||||
@ -55,13 +67,17 @@ class Hash
|
|||||||
def deep_stringify_keys! = T.unsafe(self).deep_transform_keys!(&:to_s)
|
def deep_stringify_keys! = T.unsafe(self).deep_transform_keys!(&:to_s)
|
||||||
|
|
||||||
# Returns a new hash with all keys converted to symbols, as long as
|
# Returns a new hash with all keys converted to symbols, as long as
|
||||||
# they respond to +to_sym+. This includes the keys from the root hash
|
# they respond to `to_sym`. This includes the keys from the root hash
|
||||||
# and from all nested hashes and arrays.
|
# and from all nested hashes and arrays.
|
||||||
#
|
#
|
||||||
# hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } }
|
# ### Example
|
||||||
#
|
#
|
||||||
# hash.deep_symbolize_keys
|
# ```ruby
|
||||||
# # => {:person=>{:name=>"Rob", :age=>"28"}}
|
# hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } }
|
||||||
|
#
|
||||||
|
# hash.deep_symbolize_keys
|
||||||
|
# # => {:person=>{:name=>"Rob", :age=>"28"}}
|
||||||
|
# ```
|
||||||
def deep_symbolize_keys
|
def deep_symbolize_keys
|
||||||
deep_transform_keys do |key|
|
deep_transform_keys do |key|
|
||||||
T.unsafe(key).to_sym
|
T.unsafe(key).to_sym
|
||||||
@ -71,7 +87,7 @@ class Hash
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Destructively converts all keys to symbols, as long as they respond
|
# Destructively converts all keys to symbols, as long as they respond
|
||||||
# to +to_sym+. This includes the keys from the root hash and from all
|
# to `to_sym`. This includes the keys from the root hash and from all
|
||||||
# nested hashes and arrays.
|
# nested hashes and arrays.
|
||||||
def deep_symbolize_keys!
|
def deep_symbolize_keys!
|
||||||
deep_transform_keys! do |key|
|
deep_transform_keys! do |key|
|
||||||
@ -102,7 +118,7 @@ class Hash
|
|||||||
def _deep_transform_keys_in_object!(object, &block)
|
def _deep_transform_keys_in_object!(object, &block)
|
||||||
case object
|
case object
|
||||||
when Hash
|
when Hash
|
||||||
# We can't use `each_key` here because we're updating the hash in-place
|
# We can't use `each_key` here because we're updating the hash in-place.
|
||||||
object.keys.each do |key| # rubocop:disable Style/HashEachMethods
|
object.keys.each do |key| # rubocop:disable Style/HashEachMethods
|
||||||
value = object.delete(key)
|
value = object.delete(key)
|
||||||
object[yield(key)] = _deep_transform_keys_in_object!(value, &block)
|
object[yield(key)] = _deep_transform_keys_in_object!(value, &block)
|
||||||
|
|||||||
@ -493,14 +493,20 @@ module Kernel
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Calls the given block with the passed environment variables
|
# Calls the given block with the passed environment variables
|
||||||
# added to ENV, then restores ENV afterwards.
|
# added to `ENV`, then restores `ENV` afterwards.
|
||||||
# <pre>with_env(PATH: "/bin") do
|
#
|
||||||
# system "echo $PATH"
|
# NOTE: This method is **not** thread-safe – other threads
|
||||||
# end</pre>
|
# which happen to be scheduled during the block will also
|
||||||
|
# see these environment variables.
|
||||||
|
#
|
||||||
|
# ### Example
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
|
# with_env(PATH: "/bin") do
|
||||||
|
# system "echo $PATH"
|
||||||
|
# end
|
||||||
|
# ```
|
||||||
#
|
#
|
||||||
# @note This method is *not* thread-safe - other threads
|
|
||||||
# which happen to be scheduled during the block will also
|
|
||||||
# see these environment variables.
|
|
||||||
# @api public
|
# @api public
|
||||||
def with_env(hash)
|
def with_env(hash)
|
||||||
old_values = {}
|
old_values = {}
|
||||||
|
|||||||
@ -1,24 +1,30 @@
|
|||||||
# typed: strict
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
#--
|
|
||||||
# Most objects are cloneable, but not all. For example you can't dup methods:
|
# Most objects are cloneable, but not all. For example you can't dup methods:
|
||||||
#
|
#
|
||||||
# method(:puts).dup # => TypeError: allocator undefined for Method
|
# ```ruby
|
||||||
|
# method(:puts).dup # => TypeError: allocator undefined for Method
|
||||||
|
# ```
|
||||||
#
|
#
|
||||||
# Classes may signal their instances are not duplicable removing +dup+/+clone+
|
# Classes may signal their instances are not duplicable removing +dup+/+clone+
|
||||||
# or raising exceptions from them. So, to dup an arbitrary object you normally
|
# or raising exceptions from them. So, to dup an arbitrary object you normally
|
||||||
# use an optimistic approach and are ready to catch an exception, say:
|
# use an optimistic approach and are ready to catch an exception, say:
|
||||||
#
|
#
|
||||||
# arbitrary_object.dup rescue object
|
# ```ruby
|
||||||
|
# arbitrary_object.dup rescue object
|
||||||
|
# ```
|
||||||
#
|
#
|
||||||
# Rails dups objects in a few critical spots where they are not that arbitrary.
|
# Rails dups objects in a few critical spots where they are not that arbitrary.
|
||||||
# That rescue is very expensive (like 40 times slower than a predicate), and it
|
# That `rescue` is very expensive (like 40 times slower than a predicate) and it
|
||||||
# is often triggered.
|
# is often triggered.
|
||||||
#
|
#
|
||||||
# That's why we hardcode the following cases and check duplicable? instead of
|
# That's why we hardcode the following cases and check duplicable? instead of
|
||||||
# using that rescue idiom.
|
# using that rescue idiom.
|
||||||
#++
|
# rubocop:disable Layout/EmptyLines
|
||||||
|
|
||||||
|
|
||||||
|
# rubocop:enable Layout/EmptyLines
|
||||||
class Object
|
class Object
|
||||||
# Can you safely dup this object?
|
# Can you safely dup this object?
|
||||||
#
|
#
|
||||||
@ -31,8 +37,10 @@ end
|
|||||||
class Method
|
class Method
|
||||||
# Methods are not duplicable:
|
# Methods are not duplicable:
|
||||||
#
|
#
|
||||||
# method(:puts).duplicable? # => false
|
# ```ruby
|
||||||
# method(:puts).dup # => TypeError: allocator undefined for Method
|
# method(:puts).duplicable? # => false
|
||||||
|
# method(:puts).dup # => TypeError: allocator undefined for Method
|
||||||
|
# ```
|
||||||
sig { returns(FalseClass) }
|
sig { returns(FalseClass) }
|
||||||
def duplicable? = false
|
def duplicable? = false
|
||||||
end
|
end
|
||||||
@ -40,8 +48,10 @@ end
|
|||||||
class UnboundMethod
|
class UnboundMethod
|
||||||
# Unbound methods are not duplicable:
|
# Unbound methods are not duplicable:
|
||||||
#
|
#
|
||||||
# method(:puts).unbind.duplicable? # => false
|
# ```ruby
|
||||||
# method(:puts).unbind.dup # => TypeError: allocator undefined for UnboundMethod
|
# method(:puts).unbind.duplicable? # => false
|
||||||
|
# method(:puts).unbind.dup # => TypeError: allocator undefined for UnboundMethod
|
||||||
|
# ```
|
||||||
sig { returns(FalseClass) }
|
sig { returns(FalseClass) }
|
||||||
def duplicable? = false
|
def duplicable? = false
|
||||||
end
|
end
|
||||||
@ -51,7 +61,9 @@ require "singleton"
|
|||||||
module Singleton
|
module Singleton
|
||||||
# Singleton instances are not duplicable:
|
# Singleton instances are not duplicable:
|
||||||
#
|
#
|
||||||
# Class.new.include(Singleton).instance.dup # TypeError (can't dup instance of singleton
|
# ```ruby
|
||||||
|
# Class.new.include(Singleton).instance.dup # TypeError (can't dup instance of singleton
|
||||||
|
# ```
|
||||||
sig { returns(FalseClass) }
|
sig { returns(FalseClass) }
|
||||||
def duplicable? = false
|
def duplicable? = false
|
||||||
end
|
end
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
module Homebrew
|
module Homebrew
|
||||||
module Install
|
module Install
|
||||||
# This is a list of known paths to the host dynamic linker on Linux if
|
# This is a list of known paths to the host dynamic linker on Linux if
|
||||||
# the host glibc is new enough. The symlink_ld_so method will fail if
|
# the host glibc is new enough. The symlink_ld_so method will fail if
|
||||||
# the host linker cannot be found in this list.
|
# the host linker cannot be found in this list.
|
||||||
DYNAMIC_LINKERS = %w[
|
DYNAMIC_LINKERS = %w[
|
||||||
/lib64/ld-linux-x86-64.so.2
|
/lib64/ld-linux-x86-64.so.2
|
||||||
@ -19,7 +19,7 @@ module Homebrew
|
|||||||
private_constant :DYNAMIC_LINKERS
|
private_constant :DYNAMIC_LINKERS
|
||||||
|
|
||||||
# We link GCC runtime libraries that are not specifically used for Fortran,
|
# We link GCC runtime libraries that are not specifically used for Fortran,
|
||||||
# which are linked by the GCC formula. We only use the versioned shared libraries
|
# which are linked by the GCC formula. We only use the versioned shared libraries
|
||||||
# as the other shared and static libraries are only used at build time where
|
# as the other shared and static libraries are only used at build time where
|
||||||
# GCC can find its own libraries.
|
# GCC can find its own libraries.
|
||||||
GCC_RUNTIME_LIBS = %w[
|
GCC_RUNTIME_LIBS = %w[
|
||||||
|
|||||||
@ -16,7 +16,7 @@ module Homebrew
|
|||||||
return unless @args.cask?
|
return unless @args.cask?
|
||||||
|
|
||||||
# NOTE: We don't raise an error here because we don't want
|
# NOTE: We don't raise an error here because we don't want
|
||||||
# to print the help page or a stack trace.
|
# to print the help page or a stack trace.
|
||||||
odie "Invalid `--cask` usage: Casks do not work on Linux"
|
odie "Invalid `--cask` usage: Casks do not work on Linux"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -340,7 +340,7 @@ module Homebrew
|
|||||||
else
|
else
|
||||||
inject_file_list @found, <<~EOS
|
inject_file_list @found, <<~EOS
|
||||||
libiconv files detected at a system prefix other than /usr.
|
libiconv files detected at a system prefix other than /usr.
|
||||||
Homebrew doesn't provide a libiconv formula, and expects to link against
|
Homebrew doesn't provide a libiconv formula and expects to link against
|
||||||
the system version in /usr. libiconv in other prefixes can cause
|
the system version in /usr. libiconv in other prefixes can cause
|
||||||
compile or link failure, especially if compiled with improper
|
compile or link failure, especially if compiled with improper
|
||||||
architectures. macOS itself never installs anything to /usr/local so
|
architectures. macOS itself never installs anything to /usr/local so
|
||||||
|
|||||||
@ -27,12 +27,11 @@ module Stdenv
|
|||||||
|
|
||||||
append "LDFLAGS", "-Wl,-headerpad_max_install_names"
|
append "LDFLAGS", "-Wl,-headerpad_max_install_names"
|
||||||
|
|
||||||
# sed is strict, and errors out when it encounters files with
|
# `sed` is strict and errors out when it encounters files with mixed character sets.
|
||||||
# mixed character sets
|
|
||||||
delete("LC_ALL")
|
delete("LC_ALL")
|
||||||
self["LC_CTYPE"] = "C"
|
self["LC_CTYPE"] = "C"
|
||||||
|
|
||||||
# Add lib and include etc. from the current macosxsdk to compiler flags:
|
# Add `lib` and `include` etc. from the current `macosxsdk` to compiler flags:
|
||||||
macosxsdk(formula: @formula, testing_formula:)
|
macosxsdk(formula: @formula, testing_formula:)
|
||||||
|
|
||||||
return unless MacOS::Xcode.without_clt?
|
return unless MacOS::Xcode.without_clt?
|
||||||
@ -42,8 +41,8 @@ module Stdenv
|
|||||||
end
|
end
|
||||||
|
|
||||||
def remove_macosxsdk(version = nil)
|
def remove_macosxsdk(version = nil)
|
||||||
# Clear all lib and include dirs from CFLAGS, CPPFLAGS, LDFLAGS that were
|
# Clear all `lib` and `include` dirs from `CFLAGS`, `CPPFLAGS`, `LDFLAGS` that were
|
||||||
# previously added by macosxsdk
|
# previously added by `macosxsdk`.
|
||||||
remove_from_cflags(/ ?-mmacosx-version-min=\d+\.\d+/)
|
remove_from_cflags(/ ?-mmacosx-version-min=\d+\.\d+/)
|
||||||
delete("CPATH")
|
delete("CPATH")
|
||||||
remove "LDFLAGS", "-L#{HOMEBREW_PREFIX}/lib"
|
remove "LDFLAGS", "-L#{HOMEBREW_PREFIX}/lib"
|
||||||
@ -58,14 +57,14 @@ module Stdenv
|
|||||||
if HOMEBREW_PREFIX.to_s == "/usr/local"
|
if HOMEBREW_PREFIX.to_s == "/usr/local"
|
||||||
delete("CMAKE_PREFIX_PATH")
|
delete("CMAKE_PREFIX_PATH")
|
||||||
else
|
else
|
||||||
# It was set in setup_build_environment, so we have to restore it here.
|
# It was set in `setup_build_environment`, so we have to restore it here.
|
||||||
self["CMAKE_PREFIX_PATH"] = HOMEBREW_PREFIX.to_s
|
self["CMAKE_PREFIX_PATH"] = HOMEBREW_PREFIX.to_s
|
||||||
end
|
end
|
||||||
remove "CMAKE_FRAMEWORK_PATH", "#{sdk}/System/Library/Frameworks"
|
remove "CMAKE_FRAMEWORK_PATH", "#{sdk}/System/Library/Frameworks"
|
||||||
end
|
end
|
||||||
|
|
||||||
def macosxsdk(version = nil, formula: nil, testing_formula: false)
|
def macosxsdk(version = nil, formula: nil, testing_formula: false)
|
||||||
# Sets all needed lib and include dirs to CFLAGS, CPPFLAGS, LDFLAGS.
|
# Sets all needed `lib` and `include` dirs to `CFLAGS`, `CPPFLAGS`, `LDFLAGS`.
|
||||||
remove_macosxsdk
|
remove_macosxsdk
|
||||||
min_version = version || MacOS.version
|
min_version = version || MacOS.version
|
||||||
append_to_cflags("-mmacosx-version-min=#{min_version}")
|
append_to_cflags("-mmacosx-version-min=#{min_version}")
|
||||||
|
|||||||
@ -112,7 +112,7 @@ module FormulaCellarChecks
|
|||||||
|
|
||||||
<<~EOS
|
<<~EOS
|
||||||
Libraries were compiled with a flat namespace.
|
Libraries were compiled with a flat namespace.
|
||||||
This can cause linker errors due to name collisions, and
|
This can cause linker errors due to name collisions and
|
||||||
is often due to a bug in detecting the macOS version.
|
is often due to a bug in detecting the macOS version.
|
||||||
#{flat_namespace_files * "\n "}
|
#{flat_namespace_files * "\n "}
|
||||||
EOS
|
EOS
|
||||||
|
|||||||
@ -83,8 +83,8 @@ module Hardware
|
|||||||
sysctl_bool("hw.optional.sse4_2")
|
sysctl_bool("hw.optional.sse4_2")
|
||||||
end
|
end
|
||||||
|
|
||||||
# NOTE: this is more reliable than checking uname.
|
# NOTE: This is more reliable than checking `uname`. `sysctl` returns
|
||||||
# `sysctl` returns the right answer even when running in Rosetta 2.
|
# the right answer even when running in Rosetta 2.
|
||||||
def physical_cpu_arm64?
|
def physical_cpu_arm64?
|
||||||
sysctl_bool("hw.optional.arm64")
|
sysctl_bool("hw.optional.arm64")
|
||||||
end
|
end
|
||||||
|
|||||||
@ -126,10 +126,11 @@ class Pathname
|
|||||||
|
|
||||||
mkpath
|
mkpath
|
||||||
|
|
||||||
# Use FileUtils.mv over File.rename to handle filesystem boundaries. If src
|
# Use `FileUtils.mv` over `File.rename` to handle filesystem boundaries. If `src`
|
||||||
# is a symlink, and its target is moved first, FileUtils.mv will fail:
|
# is a symlink and its target is moved first, `FileUtils.mv` will fail
|
||||||
# https://bugs.ruby-lang.org/issues/7707
|
# (https://bugs.ruby-lang.org/issues/7707).
|
||||||
# In that case, use the system "mv" command.
|
#
|
||||||
|
# In that case, use the system `mv` command.
|
||||||
if src.symlink?
|
if src.symlink?
|
||||||
raise unless Kernel.system "mv", src.to_s, dst
|
raise unless Kernel.system "mv", src.to_s, dst
|
||||||
else
|
else
|
||||||
@ -178,7 +179,9 @@ class Pathname
|
|||||||
T.unsafe(self).open("a", **open_args) { |f| f.puts(content) }
|
T.unsafe(self).open("a", **open_args) { |f| f.puts(content) }
|
||||||
end
|
end
|
||||||
|
|
||||||
# @note This always overwrites.
|
# Write to a file atomically.
|
||||||
|
#
|
||||||
|
# NOTE: This always overwrites.
|
||||||
#
|
#
|
||||||
# @api public
|
# @api public
|
||||||
sig { params(content: String).void }
|
sig { params(content: String).void }
|
||||||
@ -201,6 +204,7 @@ class Pathname
|
|||||||
# Changing file ownership failed, moving on.
|
# Changing file ownership failed, moving on.
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
begin
|
begin
|
||||||
# This operation will affect filesystem ACL's
|
# This operation will affect filesystem ACL's
|
||||||
chmod(old_stat.mode)
|
chmod(old_stat.mode)
|
||||||
|
|||||||
@ -20,7 +20,7 @@ module Homebrew
|
|||||||
if os.present?
|
if os.present?
|
||||||
return true
|
return true
|
||||||
elsif ENV["HOMEBREW_TEST_GENERIC_OS"].present?
|
elsif ENV["HOMEBREW_TEST_GENERIC_OS"].present?
|
||||||
# `:generic` bottles don't exist, and `--os` flag is not specified.
|
# `:generic` bottles don't exist and `--os` flag is not specified.
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
return true if arch.present?
|
return true if arch.present?
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -16,7 +16,8 @@ module Homebrew
|
|||||||
@assertions ||= 0
|
@assertions ||= 0
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the output of running cmd, and asserts the exit status.
|
# Returns the output of running cmd and asserts the exit status.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
def shell_output(cmd, result = 0)
|
def shell_output(cmd, result = 0)
|
||||||
ohai cmd
|
ohai cmd
|
||||||
@ -28,8 +29,9 @@ module Homebrew
|
|||||||
raise
|
raise
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the output of running the cmd with the optional input, and
|
# Returns the output of running the cmd with the optional input and
|
||||||
# optionally asserts the exit status.
|
# optionally asserts the exit status.
|
||||||
|
#
|
||||||
# @api public
|
# @api public
|
||||||
def pipe_output(cmd, input = nil, result = nil)
|
def pipe_output(cmd, input = nil, result = nil)
|
||||||
ohai cmd
|
ohai cmd
|
||||||
|
|||||||
@ -99,6 +99,8 @@ module Homebrew
|
|||||||
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def template
|
def template
|
||||||
|
# FIXME: https://github.com/errata-ai/vale/issues/818
|
||||||
|
# <!-- vale off -->
|
||||||
<<~ERB
|
<<~ERB
|
||||||
# Documentation: https://docs.brew.sh/Formula-Cookbook
|
# Documentation: https://docs.brew.sh/Formula-Cookbook
|
||||||
# https://rubydoc.brew.sh/Formula
|
# https://rubydoc.brew.sh/Formula
|
||||||
@ -183,14 +185,14 @@ module Homebrew
|
|||||||
ENV.prepend_create_path "PERL5LIB", libexec/"lib/perl5"
|
ENV.prepend_create_path "PERL5LIB", libexec/"lib/perl5"
|
||||||
ENV.prepend_path "PERL5LIB", libexec/"lib"
|
ENV.prepend_path "PERL5LIB", libexec/"lib"
|
||||||
|
|
||||||
# Stage additional dependency (Makefile.PL style)
|
# Stage additional dependency (`Makefile.PL` style).
|
||||||
# resource("").stage do
|
# resource("").stage do
|
||||||
# system "perl", "Makefile.PL", "INSTALL_BASE=\#{libexec}"
|
# system "perl", "Makefile.PL", "INSTALL_BASE=\#{libexec}"
|
||||||
# system "make"
|
# system "make"
|
||||||
# system "make", "install"
|
# system "make", "install"
|
||||||
# end
|
# end
|
||||||
|
|
||||||
# Stage additional dependency (Build.PL style)
|
# Stage additional dependency (`Build.PL` style).
|
||||||
# resource("").stage do
|
# resource("").stage do
|
||||||
# system "perl", "Build.PL", "--install_base", libexec
|
# system "perl", "Build.PL", "--install_base", libexec
|
||||||
# system "./Build"
|
# system "./Build"
|
||||||
@ -231,6 +233,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
ERB
|
ERB
|
||||||
|
# <!-- vale on -->
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -37,7 +37,6 @@ class KegOnlyReason
|
|||||||
!by_macos?
|
!by_macos?
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
return @explanation unless @explanation.empty?
|
return @explanation unless @explanation.empty?
|
||||||
|
|||||||
@ -25,7 +25,6 @@ module Homebrew
|
|||||||
@text.include? string
|
@text.include? string
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
@text
|
@text
|
||||||
|
|||||||
@ -537,19 +537,19 @@ module Formulary
|
|||||||
class FormulaLoader
|
class FormulaLoader
|
||||||
include Context
|
include Context
|
||||||
|
|
||||||
# The formula's name
|
# The formula's name.
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
attr_reader :name
|
attr_reader :name
|
||||||
|
|
||||||
# The formula's ruby file's path or filename
|
# The formula file's path.
|
||||||
sig { returns(Pathname) }
|
sig { returns(Pathname) }
|
||||||
attr_reader :path
|
attr_reader :path
|
||||||
|
|
||||||
# The name used to install the formula
|
# The name used to install the formula.
|
||||||
sig { returns(T.nilable(Pathname)) }
|
sig { returns(T.nilable(Pathname)) }
|
||||||
attr_reader :alias_path
|
attr_reader :alias_path
|
||||||
|
|
||||||
# The formula's tap (nil if it should be implicitly determined)
|
# The formula's tap (`nil` if it should be implicitly determined).
|
||||||
sig { returns(T.nilable(Tap)) }
|
sig { returns(T.nilable(Tap)) }
|
||||||
attr_reader :tap
|
attr_reader :tap
|
||||||
|
|
||||||
@ -1019,8 +1019,8 @@ module Formulary
|
|||||||
# Return a {Formula} instance for the given rack.
|
# Return a {Formula} instance for the given rack.
|
||||||
#
|
#
|
||||||
# @param spec when nil, will auto resolve the formula's spec.
|
# @param spec when nil, will auto resolve the formula's spec.
|
||||||
# @param :alias_path will be used if the formula is found not to be
|
# @param alias_path will be used if the formula is found not to be
|
||||||
# installed, and discarded if it is installed because the `alias_path` used
|
# installed and discarded if it is installed because the `alias_path` used
|
||||||
# to install the formula will be set instead.
|
# to install the formula will be set instead.
|
||||||
sig {
|
sig {
|
||||||
params(
|
params(
|
||||||
|
|||||||
@ -106,7 +106,6 @@ class GitRepository
|
|||||||
popen_git("log", "-1", "--pretty=%B", commit, "--", safe:, err: :out)&.strip
|
popen_git("log", "-1", "--pretty=%B", commit, "--", safe:, err: :out)&.strip
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s = pathname.to_s
|
def to_s = pathname.to_s
|
||||||
|
|
||||||
|
|||||||
@ -94,12 +94,12 @@ class GitHubPackages
|
|||||||
end
|
end
|
||||||
|
|
||||||
def self.repo_without_prefix(repo)
|
def self.repo_without_prefix(repo)
|
||||||
# remove redundant repo prefix for a shorter name
|
# Remove redundant repository prefix for a shorter name.
|
||||||
repo.delete_prefix("homebrew-")
|
repo.delete_prefix("homebrew-")
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.root_url(org, repo, prefix = URL_PREFIX)
|
def self.root_url(org, repo, prefix = URL_PREFIX)
|
||||||
# docker/skopeo insist on lowercase org ("repository name")
|
# `docker`/`skopeo` insist on lowercase organisation (“repository name”).
|
||||||
org = org.downcase
|
org = org.downcase
|
||||||
|
|
||||||
"#{prefix}#{org}/#{repo_without_prefix(repo)}"
|
"#{prefix}#{org}/#{repo_without_prefix(repo)}"
|
||||||
@ -115,9 +115,9 @@ class GitHubPackages
|
|||||||
end
|
end
|
||||||
|
|
||||||
def self.image_formula_name(formula_name)
|
def self.image_formula_name(formula_name)
|
||||||
# invalid docker name characters
|
# Invalid docker name characters:
|
||||||
# / makes sense because we already use it to separate repo/formula
|
# - `/` makes sense because we already use it to separate repository/formula.
|
||||||
# x makes sense because we already use it in Formulary
|
# - `x` makes sense because we already use it in `Formulary`.
|
||||||
formula_name.tr("@", "/")
|
formula_name.tr("@", "/")
|
||||||
.tr("+", "x")
|
.tr("+", "x")
|
||||||
end
|
end
|
||||||
@ -231,9 +231,9 @@ class GitHubPackages
|
|||||||
inspect_args << "--creds=#{user}:#{token}"
|
inspect_args << "--creds=#{user}:#{token}"
|
||||||
inspect_result = system_command(skopeo, print_stderr: false, args: inspect_args)
|
inspect_result = system_command(skopeo, print_stderr: false, args: inspect_args)
|
||||||
|
|
||||||
# Order here is important
|
# Order here is important.
|
||||||
if !inspect_result.status.success? && !inspect_result.stderr.match?(/(name|manifest) unknown/)
|
if !inspect_result.status.success? && !inspect_result.stderr.match?(/(name|manifest) unknown/)
|
||||||
# We got an error, and it was not about the tag or package being unknown.
|
# We got an error and it was not about the tag or package being unknown.
|
||||||
if warn_on_error
|
if warn_on_error
|
||||||
opoo "#{image_uri} inspection returned an error, skipping upload!\n#{inspect_result.stderr}"
|
opoo "#{image_uri} inspection returned an error, skipping upload!\n#{inspect_result.stderr}"
|
||||||
return
|
return
|
||||||
@ -241,11 +241,11 @@ class GitHubPackages
|
|||||||
odie "#{image_uri} inspection returned an error!\n#{inspect_result.stderr}"
|
odie "#{image_uri} inspection returned an error!\n#{inspect_result.stderr}"
|
||||||
end
|
end
|
||||||
elsif keep_old
|
elsif keep_old
|
||||||
# If the tag doesn't exist, ignore --keep-old.
|
# If the tag doesn't exist, ignore `--keep-old`.
|
||||||
keep_old = false unless inspect_result.status.success?
|
keep_old = false unless inspect_result.status.success?
|
||||||
# Otherwise, do nothing - the tag already existing is expected behaviour for --keep-old.
|
# Otherwise, do nothing - the tag already existing is expected behaviour for --keep-old.
|
||||||
elsif inspect_result.status.success?
|
elsif inspect_result.status.success?
|
||||||
# The tag already exists, and we are not passing --keep-old.
|
# The tag already exists and we are not passing `--keep-old`.
|
||||||
if warn_on_error
|
if warn_on_error
|
||||||
opoo "#{image_uri} already exists, skipping upload!"
|
opoo "#{image_uri} already exists, skipping upload!"
|
||||||
return
|
return
|
||||||
|
|||||||
@ -48,7 +48,6 @@ class Keg
|
|||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
s = []
|
s = []
|
||||||
@ -67,7 +66,6 @@ class Keg
|
|||||||
|
|
||||||
# Error for when a directory is not writable.
|
# Error for when a directory is not writable.
|
||||||
class DirectoryNotWritableError < LinkError
|
class DirectoryNotWritableError < LinkError
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
<<~EOS
|
<<~EOS
|
||||||
@ -176,11 +174,9 @@ class Keg
|
|||||||
path.parent
|
path.parent
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s = path.to_s
|
def to_s = path.to_s
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def inspect
|
def inspect
|
||||||
"#<#{self.class.name}:#{path}>"
|
"#<#{self.class.name}:#{path}>"
|
||||||
@ -556,8 +552,8 @@ class Keg
|
|||||||
|
|
||||||
src = dst.resolved_path
|
src = dst.resolved_path
|
||||||
|
|
||||||
# src itself may be a symlink, so check lstat to ensure we are dealing with
|
# `src` itself may be a symlink, so check lstat to ensure we are dealing with
|
||||||
# a directory, and not a symlink pointing at a directory (which needs to be
|
# a directory and not a symlink pointing to a directory (which needs to be
|
||||||
# treated as a file). In other words, we only want to resolve one symlink.
|
# treated as a file). In other words, we only want to resolve one symlink.
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|||||||
@ -14,7 +14,7 @@ module Language
|
|||||||
# e.g. `resource "github.com/foo/bar"`.
|
# e.g. `resource "github.com/foo/bar"`.
|
||||||
sig { params(resources: T::Array[Resource], target: T.any(String, Pathname)).void }
|
sig { params(resources: T::Array[Resource], target: T.any(String, Pathname)).void }
|
||||||
def self.stage_deps(resources, target)
|
def self.stage_deps(resources, target)
|
||||||
# odeprecated "Language::Go::stage_deps", "Go modules"
|
# odeprecated "`Language::Go.stage_deps`", "Go modules"
|
||||||
if resources.empty?
|
if resources.empty?
|
||||||
if Homebrew::EnvConfig.developer?
|
if Homebrew::EnvConfig.developer?
|
||||||
odie "Tried to stage empty Language::Go resources array"
|
odie "Tried to stage empty Language::Go resources array"
|
||||||
|
|||||||
@ -144,14 +144,14 @@ module Language
|
|||||||
|
|
||||||
# Mixin module for {Formula} adding virtualenv support features.
|
# Mixin module for {Formula} adding virtualenv support features.
|
||||||
module Virtualenv
|
module Virtualenv
|
||||||
# Instantiates, creates, and yields a {Virtualenv} object for use from
|
# Instantiates, creates and yields a {Virtualenv} object for use from
|
||||||
# {Formula#install}, which provides helper methods for instantiating and
|
# {Formula#install}, which provides helper methods for instantiating and
|
||||||
# installing packages into a Python virtualenv.
|
# installing packages into a Python virtualenv.
|
||||||
#
|
#
|
||||||
# @param venv_root [Pathname, String] the path to the root of the virtualenv
|
# @param venv_root [Pathname, String] the path to the root of the virtualenv
|
||||||
# (often `libexec/"venv"`)
|
# (often `libexec/"venv"`)
|
||||||
# @param python [String, Pathname] which interpreter to use (e.g. "python3"
|
# @param python [String, Pathname] which interpreter to use (e.g. `"python3"`
|
||||||
# or "python3.x")
|
# or `"python3.x"`)
|
||||||
# @param formula [Formula] the active {Formula}
|
# @param formula [Formula] the active {Formula}
|
||||||
# @return [Virtualenv] a {Virtualenv} instance
|
# @return [Virtualenv] a {Virtualenv} instance
|
||||||
sig {
|
sig {
|
||||||
@ -166,7 +166,7 @@ module Language
|
|||||||
def virtualenv_create(venv_root, python = "python", formula = T.cast(self, Formula),
|
def virtualenv_create(venv_root, python = "python", formula = T.cast(self, Formula),
|
||||||
system_site_packages: true, without_pip: true)
|
system_site_packages: true, without_pip: true)
|
||||||
# Limit deprecation to 3.12+ for now (or if we can't determine the version).
|
# Limit deprecation to 3.12+ for now (or if we can't determine the version).
|
||||||
# Some used this argument for setuptools, which we no longer bundle since 3.12.
|
# Some used this argument for `setuptools`, which we no longer bundle since 3.12.
|
||||||
unless without_pip
|
unless without_pip
|
||||||
python_version = Language::Python.major_minor_version(python)
|
python_version = Language::Python.major_minor_version(python)
|
||||||
if python_version.nil? || python_version.null? || python_version >= "3.12"
|
if python_version.nil? || python_version.null? || python_version >= "3.12"
|
||||||
@ -198,8 +198,8 @@ module Language
|
|||||||
|
|
||||||
# Returns true if a formula option for the specified python is currently
|
# Returns true if a formula option for the specified python is currently
|
||||||
# active or if the specified python is required by the formula. Valid
|
# active or if the specified python is required by the formula. Valid
|
||||||
# inputs are "python", "python2", and :python3. Note that
|
# inputs are `"python"`, `"python2"` and `:python3`. Note that
|
||||||
# "with-python", "without-python", "with-python@2", and "without-python@2"
|
# `"with-python"`, `"without-python"`, `"with-python@2"` and `"without-python@2"`
|
||||||
# formula options are handled correctly even if not associated with any
|
# formula options are handled correctly even if not associated with any
|
||||||
# corresponding depends_on statement.
|
# corresponding depends_on statement.
|
||||||
sig { params(python: String).returns(T::Boolean) }
|
sig { params(python: String).returns(T::Boolean) }
|
||||||
@ -211,7 +211,7 @@ module Language
|
|||||||
|
|
||||||
# Helper method for the common case of installing a Python application.
|
# Helper method for the common case of installing a Python application.
|
||||||
# Creates a virtualenv in `libexec`, installs all `resource`s defined
|
# Creates a virtualenv in `libexec`, installs all `resource`s defined
|
||||||
# on the formula, and then installs the formula. An options hash may be
|
# on the formula and then installs the formula. An options hash may be
|
||||||
# passed (e.g. `:using => "python"`) to override the default, guessed
|
# passed (e.g. `:using => "python"`) to override the default, guessed
|
||||||
# formula preference for python or python@x.y, or to resolve an ambiguous
|
# formula preference for python or python@x.y, or to resolve an ambiguous
|
||||||
# case where it's not clear whether python or python@x.y should be the
|
# case where it's not clear whether python or python@x.y should be the
|
||||||
|
|||||||
@ -16,15 +16,20 @@ class LazyObject < Delegator
|
|||||||
@__delegate__ = @__callable__.call
|
@__delegate__ = @__callable__.call
|
||||||
# rubocop:enable Naming/MemoizedInstanceVariableName
|
# rubocop:enable Naming/MemoizedInstanceVariableName
|
||||||
end
|
end
|
||||||
|
private :__getobj__
|
||||||
|
|
||||||
def __setobj__(callable)
|
def __setobj__(callable)
|
||||||
@__callable__ = callable
|
@__callable__ = callable
|
||||||
end
|
end
|
||||||
|
private :__setobj__
|
||||||
|
|
||||||
# Forward to the inner object to make lazy objects type-checkable.
|
# Forward to the inner object to make lazy objects type-checkable.
|
||||||
|
#
|
||||||
|
# @!visibility private
|
||||||
def is_a?(klass)
|
def is_a?(klass)
|
||||||
# see https://sorbet.org/docs/faq#how-can-i-fix-type-errors-that-arise-from-super
|
# see https://sorbet.org/docs/faq#how-can-i-fix-type-errors-that-arise-from-super
|
||||||
T.bind(self, T.untyped)
|
T.bind(self, T.untyped)
|
||||||
|
|
||||||
__getobj__.is_a?(klass) || super
|
__getobj__.is_a?(klass) || super
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -39,9 +39,11 @@ module Homebrew
|
|||||||
) do
|
) do
|
||||||
extend Forwardable
|
extend Forwardable
|
||||||
|
|
||||||
|
# @!attribute [r] version
|
||||||
# @api public
|
# @api public
|
||||||
delegate version: :bundle_version
|
delegate version: :bundle_version
|
||||||
|
|
||||||
|
# @!attribute [r] short_version
|
||||||
# @api public
|
# @api public
|
||||||
delegate short_version: :bundle_version
|
delegate short_version: :bundle_version
|
||||||
end
|
end
|
||||||
|
|||||||
@ -13,7 +13,7 @@ module Homebrew
|
|||||||
# Livecheck has historically prioritized the {Git} strategy over others
|
# Livecheck has historically prioritized the {Git} strategy over others
|
||||||
# and this behavior was continued when the priority setup was created.
|
# and this behavior was continued when the priority setup was created.
|
||||||
# This is partly related to Livecheck checking formula URLs in order of
|
# This is partly related to Livecheck checking formula URLs in order of
|
||||||
# `head`, `stable`, and then `homepage`. The higher priority here may
|
# `head`, `stable` and then `homepage`. The higher priority here may
|
||||||
# be removed (or altered) in the future if we reevaluate this particular
|
# be removed (or altered) in the future if we reevaluate this particular
|
||||||
# behavior.
|
# behavior.
|
||||||
#
|
#
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
module Homebrew
|
module Homebrew
|
||||||
module Livecheck
|
module Livecheck
|
||||||
module Strategy
|
module Strategy
|
||||||
# The {Json} strategy fetches content at a URL, parses it as JSON, and
|
# The {Json} strategy fetches content at a URL, parses it as JSON and
|
||||||
# provides the parsed data to a `strategy` block. If a regex is present
|
# provides the parsed data to a `strategy` block. If a regex is present
|
||||||
# in the `livecheck` block, it should be passed as the second argument to
|
# in the `livecheck` block, it should be passed as the second argument to
|
||||||
# the `strategy` block.
|
# the `strategy` block.
|
||||||
|
|||||||
@ -54,12 +54,15 @@ module Homebrew
|
|||||||
) do
|
) do
|
||||||
extend Forwardable
|
extend Forwardable
|
||||||
|
|
||||||
|
# @!attribute [r] version
|
||||||
# @api public
|
# @api public
|
||||||
delegate version: :bundle_version
|
delegate version: :bundle_version
|
||||||
|
|
||||||
|
# @!attribute [r] short_version
|
||||||
# @api public
|
# @api public
|
||||||
delegate short_version: :bundle_version
|
delegate short_version: :bundle_version
|
||||||
|
|
||||||
|
# @!attribute [r] nice_version
|
||||||
# @api public
|
# @api public
|
||||||
delegate nice_version: :bundle_version
|
delegate nice_version: :bundle_version
|
||||||
end
|
end
|
||||||
|
|||||||
@ -5,7 +5,7 @@ module Homebrew
|
|||||||
module Livecheck
|
module Livecheck
|
||||||
module Strategy
|
module Strategy
|
||||||
# The {Xml} strategy fetches content at a URL, parses it as XML using
|
# The {Xml} strategy fetches content at a URL, parses it as XML using
|
||||||
# `REXML`, and provides the `REXML::Document` to a `strategy` block.
|
# `REXML` and provides the `REXML::Document` to a `strategy` block.
|
||||||
# If a regex is present in the `livecheck` block, it should be passed
|
# If a regex is present in the `livecheck` block, it should be passed
|
||||||
# as the second argument to the `strategy` block.
|
# as the second argument to the `strategy` block.
|
||||||
#
|
#
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
module Homebrew
|
module Homebrew
|
||||||
module Livecheck
|
module Livecheck
|
||||||
module Strategy
|
module Strategy
|
||||||
# The {Yaml} strategy fetches content at a URL, parses it as YAML, and
|
# The {Yaml} strategy fetches content at a URL, parses it as YAML and
|
||||||
# provides the parsed data to a `strategy` block. If a regex is present
|
# provides the parsed data to a `strategy` block. If a regex is present
|
||||||
# in the `livecheck` block, it should be passed as the second argument to
|
# in the `livecheck` block, it should be passed as the second argument to
|
||||||
# the `strategy` block.
|
# the `strategy` block.
|
||||||
|
|||||||
@ -106,7 +106,6 @@ class Locale
|
|||||||
locale_groups.find { |locales| locales.any? { |locale| include?(locale) } }
|
locale_groups.find { |locales| locales.any? { |locale| include?(locale) } }
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
[@language, @script, @region].compact.join("-")
|
[@language, @script, @region].compact.join("-")
|
||||||
|
|||||||
@ -132,6 +132,7 @@ class MacOSVersion < Version
|
|||||||
alias requires_popcnt? requires_nehalem_cpu?
|
alias requires_popcnt? requires_nehalem_cpu?
|
||||||
|
|
||||||
# Represents the absence of a version.
|
# Represents the absence of a version.
|
||||||
|
#
|
||||||
# NOTE: Constructor needs to called with an arbitrary macOS-like version which is then set to `nil`.
|
# NOTE: Constructor needs to called with an arbitrary macOS-like version which is then set to `nil`.
|
||||||
NULL = MacOSVersion.new("10.0").tap { |v| v.instance_variable_set(:@version, nil) }.freeze
|
NULL = MacOSVersion.new("10.0").tap { |v| v.instance_variable_set(:@version, nil) }.freeze
|
||||||
end
|
end
|
||||||
@ -141,7 +142,7 @@ require "lazy_object"
|
|||||||
module MacOSVersionErrorCompat
|
module MacOSVersionErrorCompat
|
||||||
def const_missing(name)
|
def const_missing(name)
|
||||||
if name == :MacOSVersionError
|
if name == :MacOSVersionError
|
||||||
odisabled "MacOSVersionError", "MacOSVersion::Error"
|
odisabled "`MacOSVersionError`", "`MacOSVersion::Error`"
|
||||||
return MacOSVersion::Error
|
return MacOSVersion::Error
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -158,7 +159,7 @@ end
|
|||||||
|
|
||||||
module MacOSVersions
|
module MacOSVersions
|
||||||
SYMBOLS = LazyObject.new do # rubocop:disable Style/MutableConstant
|
SYMBOLS = LazyObject.new do # rubocop:disable Style/MutableConstant
|
||||||
odisabled "MacOSVersions::SYMBOLS", "MacOSVersion::SYMBOLS"
|
odisabled "`MacOSVersions::SYMBOLS`", "`MacOSVersion::SYMBOLS`"
|
||||||
MacOSVersion::SYMBOLS
|
MacOSVersion::SYMBOLS
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -167,7 +168,7 @@ module OS
|
|||||||
module Mac
|
module Mac
|
||||||
# TODO: Replace `::Version` with `Version` when this is removed.
|
# TODO: Replace `::Version` with `Version` when this is removed.
|
||||||
Version = LazyObject.new do # rubocop:disable Style/MutableConstant
|
Version = LazyObject.new do # rubocop:disable Style/MutableConstant
|
||||||
odisabled "OS::Mac::Version", "MacOSVersion"
|
odisabled "`OS::Mac::Version`", "`MacOSVersion`"
|
||||||
MacOSVersion
|
MacOSVersion
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -142,7 +142,7 @@ module Homebrew
|
|||||||
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def self.global_cask_options_manpage
|
def self.global_cask_options_manpage
|
||||||
lines = ["These options are applicable to the `install`, `reinstall`, and `upgrade` " \
|
lines = ["These options are applicable to the `install`, `reinstall` and `upgrade` " \
|
||||||
"subcommands with the `--cask` switch.\n"]
|
"subcommands with the `--cask` switch.\n"]
|
||||||
lines += Homebrew::CLI::Parser.global_cask_options.map do |_, long, kwargs|
|
lines += Homebrew::CLI::Parser.global_cask_options.map do |_, long, kwargs|
|
||||||
generate_option_doc(nil, long.chomp("="), kwargs.fetch(:description))
|
generate_option_doc(nil, long.chomp("="), kwargs.fetch(:description))
|
||||||
|
|||||||
@ -287,17 +287,18 @@ class Migrator
|
|||||||
def repin
|
def repin
|
||||||
return unless pinned?
|
return unless pinned?
|
||||||
|
|
||||||
# old_pin_record is a relative symlink and when we try to to read it
|
# `old_pin_record` is a relative symlink and when we try to to read it
|
||||||
# from <dir> we actually try to find file
|
# from <dir> we actually try to find file
|
||||||
# <dir>/../<...>/../Cellar/name/version.
|
# <dir>/../<...>/../Cellar/name/version.
|
||||||
# To repin formula we need to update the link thus that it points to
|
# To repin formula we need to update the link thus that it points to
|
||||||
# the right directory.
|
# the right directory.
|
||||||
# NOTE: old_pin_record.realpath.sub(oldname, newname) is unacceptable
|
#
|
||||||
# here, because it resolves every symlink for old_pin_record and then
|
# NOTE: `old_pin_record.realpath.sub(oldname, newname)` is unacceptable
|
||||||
|
# here, because it resolves every symlink for `old_pin_record` and then
|
||||||
# substitutes oldname with newname. It breaks things like
|
# substitutes oldname with newname. It breaks things like
|
||||||
# Pathname#make_relative_symlink, where Pathname#relative_path_from
|
# `Pathname#make_relative_symlink`, where `Pathname#relative_path_from`
|
||||||
# is used to find relative path from source to destination parent and
|
# is used to find the relative path from source to destination parent
|
||||||
# it assumes no symlinks.
|
# and it assumes no symlinks.
|
||||||
src_oldname = (old_pin_record.dirname/old_pin_link_record).expand_path
|
src_oldname = (old_pin_record.dirname/old_pin_link_record).expand_path
|
||||||
new_pin_record.make_relative_symlink(src_oldname.sub(oldname, newname))
|
new_pin_record.make_relative_symlink(src_oldname.sub(oldname, newname))
|
||||||
old_pin_record.delete
|
old_pin_record.delete
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
# typed: true
|
# typed: true
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
# Performs {Formula#mktemp}'s functionality, and tracks the results.
|
# Performs {Formula#mktemp}'s functionality and tracks the results.
|
||||||
# Each instance is only intended to be used once.
|
# Each instance is only intended to be used once.
|
||||||
class Mktemp
|
class Mktemp
|
||||||
include FileUtils
|
include FileUtils
|
||||||
@ -38,7 +38,6 @@ class Mktemp
|
|||||||
@quiet = true
|
@quiet = true
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
"[Mktemp: #{tmpdir} retain=#{@retain} quiet=#{@quiet}]"
|
"[Mktemp: #{tmpdir} retain=#{@retain} quiet=#{@quiet}]"
|
||||||
|
|||||||
@ -11,7 +11,6 @@ class Option
|
|||||||
@description = description
|
@description = description
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s = flag
|
def to_s = flag
|
||||||
|
|
||||||
@ -30,7 +29,6 @@ class Option
|
|||||||
name.hash
|
name.hash
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def inspect
|
def inspect
|
||||||
"#<#{self.class.name}: #{flag.inspect}>"
|
"#<#{self.class.name}: #{flag.inspect}>"
|
||||||
@ -134,13 +132,11 @@ class Options
|
|||||||
|
|
||||||
alias to_ary to_a
|
alias to_ary to_a
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
@options.map(&:to_s).join(" ")
|
@options.map(&:to_s).join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def inspect
|
def inspect
|
||||||
"#<#{self.class.name}: #{to_a.inspect}>"
|
"#<#{self.class.name}: #{to_a.inspect}>"
|
||||||
|
|||||||
@ -173,8 +173,8 @@ module OS
|
|||||||
# using that.
|
# using that.
|
||||||
# As of Xcode 10, the Unix-style headers are installed via a
|
# As of Xcode 10, the Unix-style headers are installed via a
|
||||||
# separate package, so we can't rely on their being present.
|
# separate package, so we can't rely on their being present.
|
||||||
# This will only look up SDKs on Xcode 10 or newer, and still
|
# This will only look up SDKs on Xcode 10 or newer and still
|
||||||
# return nil SDKs for Xcode 9 and older.
|
# return `nil` SDKs for Xcode 9 and older.
|
||||||
sig { override.returns(String) }
|
sig { override.returns(String) }
|
||||||
def sdk_prefix
|
def sdk_prefix
|
||||||
@sdk_prefix ||= if CLT.provides_sdk?
|
@sdk_prefix ||= if CLT.provides_sdk?
|
||||||
|
|||||||
@ -51,7 +51,6 @@ class EmbeddedPatch
|
|||||||
Utils.safe_popen_write("patch", *args) { |p| p.write(data) }
|
Utils.safe_popen_write("patch", *args) { |p| p.write(data) }
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def inspect
|
def inspect
|
||||||
"#<#{self.class.name}: #{strip.inspect}>"
|
"#<#{self.class.name}: #{strip.inspect}>"
|
||||||
@ -151,7 +150,6 @@ class ExternalPatch
|
|||||||
raise BuildError.new(f, cmd, args, ENV.to_hash)
|
raise BuildError.new(f, cmd, args, ENV.to_hash)
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def inspect
|
def inspect
|
||||||
"#<#{self.class.name}: #{strip.inspect} #{url.inspect}>"
|
"#<#{self.class.name}: #{strip.inspect} #{url.inspect}>"
|
||||||
|
|||||||
@ -39,7 +39,6 @@ class PkgVersion
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s = to_str
|
def to_s = to_str
|
||||||
|
|
||||||
|
|||||||
@ -140,7 +140,6 @@ class Requirement
|
|||||||
[self.class, name, tags].hash
|
[self.class, name, tags].hash
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def inspect
|
def inspect
|
||||||
"#<#{self.class.name}: #{tags.inspect}>"
|
"#<#{self.class.name}: #{tags.inspect}>"
|
||||||
|
|||||||
@ -27,7 +27,6 @@ class ArchRequirement < Requirement
|
|||||||
"The #{@arch} architecture is required for this software."
|
"The #{@arch} architecture is required for this software."
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def inspect
|
def inspect
|
||||||
"#<#{self.class.name}: arch=#{@arch.to_s.inspect} #{tags.inspect}>"
|
"#<#{self.class.name}: arch=#{@arch.to_s.inspect} #{tags.inspect}>"
|
||||||
|
|||||||
@ -96,7 +96,6 @@ class MacOSRequirement < Requirement
|
|||||||
[super, comparator, version].hash
|
[super, comparator, version].hash
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def inspect
|
def inspect
|
||||||
"#<#{self.class.name}: version#{@comparator}#{@version.to_s.inspect} #{tags.inspect}>"
|
"#<#{self.class.name}: version#{@comparator}#{@version.to_s.inspect} #{tags.inspect}>"
|
||||||
|
|||||||
@ -48,7 +48,6 @@ class XcodeRequirement < Requirement
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def inspect
|
def inspect
|
||||||
"#<#{self.class.name}: version>=#{@version.inspect} #{tags.inspect}>"
|
"#<#{self.class.name}: version>=#{@version.inspect} #{tags.inspect}>"
|
||||||
|
|||||||
@ -146,17 +146,22 @@ class Resource < Downloadable
|
|||||||
super(verify_download_integrity:)
|
super(verify_download_integrity:)
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!attribute [w] livecheck
|
|
||||||
# {Livecheck} can be used to check for newer versions of the software.
|
# {Livecheck} can be used to check for newer versions of the software.
|
||||||
# This method evaluates the DSL specified in the livecheck block of the
|
# This method evaluates the DSL specified in the livecheck block of the
|
||||||
# {Resource} (if it exists) and sets the instance variables of a {Livecheck}
|
# {Resource} (if it exists) and sets the instance variables of a {Livecheck}
|
||||||
# object accordingly. This is used by `brew livecheck` to check for newer
|
# object accordingly. This is used by `brew livecheck` to check for newer
|
||||||
# versions of the software.
|
# versions of the software.
|
||||||
#
|
#
|
||||||
# <pre>livecheck do
|
# ### Example
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
|
# livecheck do
|
||||||
# url "https://example.com/foo/releases"
|
# url "https://example.com/foo/releases"
|
||||||
# regex /foo-(\d+(?:\.\d+)+)\.tar/
|
# regex /foo-(\d+(?:\.\d+)+)\.tar/
|
||||||
# end</pre>
|
# end
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# @!attribute [w] livecheck
|
||||||
def livecheck(&block)
|
def livecheck(&block)
|
||||||
return @livecheck unless block
|
return @livecheck unless block
|
||||||
|
|
||||||
@ -165,8 +170,8 @@ class Resource < Downloadable
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Whether a livecheck specification is defined or not.
|
# Whether a livecheck specification is defined or not.
|
||||||
# It returns true when a livecheck block is present in the {Resource} and
|
# It returns true when a `livecheck` block is present in the {Resource} and
|
||||||
# false otherwise, and is used by livecheck.
|
# false otherwise and is used by livecheck.
|
||||||
def livecheckable?
|
def livecheckable?
|
||||||
@livecheckable == true
|
@livecheckable == true
|
||||||
end
|
end
|
||||||
@ -302,7 +307,6 @@ class ResourceStageContext
|
|||||||
@staging = staging
|
@staging = staging
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
"<#{self.class}: resource=#{resource} staging=#{staging}>"
|
"<#{self.class}: resource=#{resource} staging=#{staging}>"
|
||||||
|
|||||||
@ -4,27 +4,26 @@
|
|||||||
module RuboCop
|
module RuboCop
|
||||||
module Cop
|
module Cop
|
||||||
module Homebrew
|
module Homebrew
|
||||||
# Checks for code that can be written with simpler conditionals
|
# Checks for code that can be simplified using `Object#blank?`.
|
||||||
# using `Object#blank?`.
|
|
||||||
#
|
#
|
||||||
# @note
|
# NOTE: Auto-correction for this cop is unsafe because `' '.empty?` returns `false`,
|
||||||
# This cop is unsafe autocorrection, because `' '.empty?` returns false,
|
# but `' '.blank?` returns `true`. Therefore, auto-correction is not compatible
|
||||||
# but `' '.blank?` returns true. Therefore, autocorrection is not compatible
|
# if the receiver is a non-empty blank string.
|
||||||
# if the receiver is a non-empty blank string, tab, or newline meta characters.
|
|
||||||
#
|
#
|
||||||
# @example
|
# ### Example
|
||||||
# # Converts usages of `nil? || empty?` to `blank?`
|
|
||||||
#
|
#
|
||||||
# # bad
|
# ```ruby
|
||||||
# foo.nil? || foo.empty?
|
# # bad
|
||||||
# foo == nil || foo.empty?
|
# foo.nil? || foo.empty?
|
||||||
|
# foo == nil || foo.empty?
|
||||||
#
|
#
|
||||||
# # good
|
# # good
|
||||||
# foo.blank?
|
# foo.blank?
|
||||||
|
# ```
|
||||||
class Blank < Base
|
class Blank < Base
|
||||||
extend AutoCorrector
|
extend AutoCorrector
|
||||||
|
|
||||||
MSG_NIL_OR_EMPTY = "Use `%<prefer>s` instead of `%<current>s`."
|
MSG = "Use `%<prefer>s` instead of `%<current>s`."
|
||||||
|
|
||||||
# `(send nil $_)` is not actually a valid match for an offense. Nodes
|
# `(send nil $_)` is not actually a valid match for an offense. Nodes
|
||||||
# that have a single method call on the left hand side
|
# that have a single method call on the left hand side
|
||||||
@ -49,7 +48,7 @@ module RuboCop
|
|||||||
nil_or_empty?(node) do |var1, var2|
|
nil_or_empty?(node) do |var1, var2|
|
||||||
return if var1 != var2
|
return if var1 != var2
|
||||||
|
|
||||||
message = format(MSG_NIL_OR_EMPTY, prefer: replacement(var1), current: node.source)
|
message = format(MSG, prefer: replacement(var1), current: node.source)
|
||||||
add_offense(node, message:) do |corrector|
|
add_offense(node, message:) do |corrector|
|
||||||
autocorrect(corrector, node)
|
autocorrect(corrector, node)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -44,7 +44,7 @@ module RuboCop
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Separate the lines into those that should be sorted and those that should not
|
# Separate the lines into those that should be sorted and those that should not
|
||||||
# ie. skip the opening and closing brackets of the array
|
# i.e. skip the opening and closing brackets of the array.
|
||||||
to_sort, to_keep = combined_source.partition { |line| !line.include?("[") && !line.include?("]") }
|
to_sort, to_keep = combined_source.partition { |line| !line.include?("[") && !line.include?("]") }
|
||||||
|
|
||||||
# Sort the lines that should be sorted
|
# Sort the lines that should be sorted
|
||||||
|
|||||||
@ -9,20 +9,23 @@ module RuboCop
|
|||||||
module Cask
|
module Cask
|
||||||
# This cop makes sure that OS conditionals are consistent.
|
# This cop makes sure that OS conditionals are consistent.
|
||||||
#
|
#
|
||||||
# @example
|
# ### Example
|
||||||
# # bad
|
|
||||||
# cask 'foo' do
|
|
||||||
# if MacOS.version == :high_sierra
|
|
||||||
# sha256 "..."
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
#
|
#
|
||||||
# # good
|
# ```ruby
|
||||||
# cask 'foo' do
|
# # bad
|
||||||
# on_high_sierra do
|
# cask 'foo' do
|
||||||
# sha256 "..."
|
# if MacOS.version == :high_sierra
|
||||||
# end
|
# sha256 "..."
|
||||||
# end
|
# end
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# # good
|
||||||
|
# cask 'foo' do
|
||||||
|
# on_high_sierra do
|
||||||
|
# sha256 "..."
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
# ```
|
||||||
class OnSystemConditionals < Base
|
class OnSystemConditionals < Base
|
||||||
extend Forwardable
|
extend Forwardable
|
||||||
extend AutoCorrector
|
extend AutoCorrector
|
||||||
|
|||||||
@ -6,16 +6,17 @@ module RuboCop
|
|||||||
module Cask
|
module Cask
|
||||||
# This cop checks that a cask's `url` stanza is formatted correctly.
|
# This cop checks that a cask's `url` stanza is formatted correctly.
|
||||||
#
|
#
|
||||||
# @example
|
# ### Example
|
||||||
# # bad
|
|
||||||
# url "https://example.com/download/foo.dmg",
|
|
||||||
# verified: "https://example.com/download"
|
|
||||||
#
|
#
|
||||||
|
# ```ruby
|
||||||
|
# # bad
|
||||||
|
# url "https://example.com/download/foo.dmg",
|
||||||
|
# verified: "https://example.com/download"
|
||||||
#
|
#
|
||||||
# # good
|
# # good
|
||||||
# url "https://example.com/download/foo.dmg",
|
# url "https://example.com/download/foo.dmg",
|
||||||
# verified: "example.com/download/"
|
# verified: "example.com/download/"
|
||||||
#
|
# ```
|
||||||
class Url < Base
|
class Url < Base
|
||||||
extend AutoCorrector
|
extend AutoCorrector
|
||||||
extend Forwardable
|
extend Forwardable
|
||||||
@ -43,7 +44,7 @@ module RuboCop
|
|||||||
|
|
||||||
# Skip if the URL and the verified value are the same.
|
# Skip if the URL and the verified value are the same.
|
||||||
next if value_node.source == url_stanza.source.gsub(%r{^"https?://}, "\"")
|
next if value_node.source == url_stanza.source.gsub(%r{^"https?://}, "\"")
|
||||||
# Skip if the URL has two path components, eg: `https://github.com/google/fonts.git`.
|
# Skip if the URL has two path components, e.g. `https://github.com/google/fonts.git`.
|
||||||
next if url_stanza.source.gsub(%r{^"https?://}, "\"").count("/") == 2
|
next if url_stanza.source.gsub(%r{^"https?://}, "\"").count("/") == 2
|
||||||
# Skip if the verified value ends with a slash.
|
# Skip if the verified value ends with a slash.
|
||||||
next if value_node.str_content.end_with?("/")
|
next if value_node.str_content.end_with?("/")
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user