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
|
||||
run: brew install vale
|
||||
|
||||
- name: Run vale for docs linting
|
||||
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}/docs
|
||||
run: vale .
|
||||
- name: Lint docs
|
||||
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||
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
|
||||
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/rbi-*/
|
||||
**/vendor/bundle/ruby/*/gems/rdoc-*/
|
||||
**/vendor/bundle/ruby/*/gems/redcarpet-*/
|
||||
**/vendor/bundle/ruby/*/gems/regexp_parser-*/
|
||||
**/vendor/bundle/ruby/*/gems/rexml-*/
|
||||
**/vendor/bundle/ruby/*/gems/rspec-*/
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
StylesPath = ./docs/vale-styles
|
||||
|
||||
[*.md]
|
||||
[formats]
|
||||
rb = md
|
||||
|
||||
[*.{md,rb}]
|
||||
BasedOnStyles = Homebrew
|
||||
|
||||
@ -70,6 +70,11 @@ Style/Documentation:
|
||||
- version.rb
|
||||
- tap.rb
|
||||
|
||||
Homebrew/NegateInclude:
|
||||
Exclude:
|
||||
# YARD runs stand-alone.
|
||||
- yard/docstring_parser.rb
|
||||
|
||||
Style/DocumentationMethod:
|
||||
Include:
|
||||
- "formula.rb"
|
||||
|
||||
@ -16,6 +16,7 @@ end
|
||||
# installed gems (should all be require: false)
|
||||
# ALL gems that are not vendored should be in a group
|
||||
group :doc, optional: true do
|
||||
gem "redcarpet", require: false
|
||||
gem "yard", require: false
|
||||
gem "yard-sorbet", require: false
|
||||
end
|
||||
|
||||
@ -53,6 +53,7 @@ GEM
|
||||
rbi (0.1.12)
|
||||
prism (>= 0.18.0, < 0.28)
|
||||
sorbet-runtime (>= 0.5.9204)
|
||||
redcarpet (3.6.0)
|
||||
regexp_parser (2.9.0)
|
||||
rexml (3.2.6)
|
||||
rspec (3.13.0)
|
||||
@ -175,6 +176,7 @@ DEPENDENCIES
|
||||
patchelf
|
||||
plist
|
||||
pry
|
||||
redcarpet
|
||||
rexml
|
||||
rspec
|
||||
rspec-github
|
||||
|
||||
@ -60,7 +60,6 @@ class PATH
|
||||
@paths.join(File::PATH_SEPARATOR)
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s = to_str
|
||||
|
||||
|
||||
@ -6,9 +6,10 @@ require "cli/parser"
|
||||
module Homebrew
|
||||
# Subclass this to implement a `brew` command. This is preferred to declaring a named function in the `Homebrew`
|
||||
# module, because:
|
||||
#
|
||||
# - Each Command lives in an isolated namespace.
|
||||
# - 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.
|
||||
#
|
||||
# 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) }
|
||||
def self.gh_executable
|
||||
# NOTE: We disable HOMEBREW_VERIFY_ATTESTATIONS when installing `gh` itself,
|
||||
# to prevent a cycle during bootstrapping. This can eventually be resolved
|
||||
# by vendoring a pure-Ruby Sigstore verifier client.
|
||||
# to prevent a cycle during bootstrapping. This can eventually be resolved
|
||||
# by vendoring a pure-Ruby Sigstore verifier client.
|
||||
@gh_executable ||= T.let(with_env("HOMEBREW_VERIFY_ATTESTATIONS" => nil) do
|
||||
ensure_executable!("gh")
|
||||
end, T.nilable(Pathname))
|
||||
|
||||
@ -265,7 +265,7 @@ EOS
|
||||
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() {
|
||||
local item=$1
|
||||
shift
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# Note: that we use a non-standard config file name to reduce
|
||||
# name clashes with other IRB config files like `.irbrc`.
|
||||
# Note #2: This doesn't work with system Ruby for some reason.
|
||||
# NOTE: We use a non-standard config file name to reduce name clashes with
|
||||
# other IRB config files like `.irbrc`.
|
||||
# NOTE: This doesn't work with system Ruby for some reason.
|
||||
|
||||
require 'irb/completion'
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@ class BuildEnvironment
|
||||
# DSL for specifying build environment settings.
|
||||
module DSL
|
||||
# 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)
|
||||
super
|
||||
child.instance_eval do
|
||||
|
||||
@ -9,16 +9,26 @@ class BuildOptions
|
||||
end
|
||||
|
||||
# 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"
|
||||
# ```
|
||||
#
|
||||
# # 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"
|
||||
# args << "--with-example2"
|
||||
# else
|
||||
# args << "--with-example1"
|
||||
# end</pre>
|
||||
# end
|
||||
# ```
|
||||
def with?(val)
|
||||
option_names = val.respond_to?(:option_names) ? val.option_names : [val]
|
||||
|
||||
@ -34,7 +44,12 @@ class BuildOptions
|
||||
end
|
||||
|
||||
# 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)
|
||||
!with?(val)
|
||||
end
|
||||
@ -45,19 +60,33 @@ class BuildOptions
|
||||
end
|
||||
|
||||
# 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?
|
||||
# args << "--i-want-pizza"
|
||||
# args << "--and-a-cold-beer" if build.with? "cold-beer"
|
||||
# end</pre>
|
||||
# end
|
||||
# ```
|
||||
def head?
|
||||
include? "HEAD"
|
||||
end
|
||||
|
||||
# True if a {Formula} is being built with {Formula.stable} instead of {Formula.head}.
|
||||
# This is the default.
|
||||
# <pre>args << "--some-beta" if build.head?</pre>
|
||||
#
|
||||
# ### Example
|
||||
#
|
||||
# ```ruby
|
||||
# args << "--some-beta" if build.head?
|
||||
# ```
|
||||
def stable?
|
||||
!head?
|
||||
end
|
||||
|
||||
@ -147,7 +147,6 @@ module Cask
|
||||
cask.config
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
"#{summarize} (#{self.class.english_name})"
|
||||
|
||||
@ -685,7 +685,7 @@ module Cask
|
||||
|
||||
sig { void }
|
||||
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?
|
||||
|
||||
user, repo = get_repo_data(%r{https?://github\.com/([^/]+)/([^/]+)/?.*}) if online?
|
||||
@ -699,7 +699,7 @@ module Cask
|
||||
|
||||
sig { void }
|
||||
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?
|
||||
|
||||
user, repo = get_repo_data(%r{https?://gitlab\.com/([^/]+)/([^/]+)/?.*}) if online?
|
||||
|
||||
@ -78,7 +78,8 @@ module Cask
|
||||
@allow_reassignment = allow_reassignment
|
||||
@loaded_from_api = loaded_from_api
|
||||
@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)
|
||||
|
||||
@default_config = config || Config.new
|
||||
@ -323,11 +324,9 @@ module Cask
|
||||
end
|
||||
|
||||
# @api public
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s = token
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def inspect
|
||||
"#<Cask #{token}#{sourcefile_path&.to_s&.prepend(" ")}>"
|
||||
|
||||
@ -112,6 +112,16 @@ module Cask
|
||||
@token = cask.token
|
||||
end
|
||||
|
||||
# Specifies the cask's name.
|
||||
#
|
||||
# NOTE: Multiple names can be specified.
|
||||
#
|
||||
# ### Example
|
||||
#
|
||||
# ```ruby
|
||||
# name "Visual Studio Code"
|
||||
# ```
|
||||
#
|
||||
# @api public
|
||||
def name(*args)
|
||||
@name ||= []
|
||||
@ -120,6 +130,14 @@ module Cask
|
||||
@name.concat(args.flatten)
|
||||
end
|
||||
|
||||
# Describes the cask.
|
||||
#
|
||||
# ### Example
|
||||
#
|
||||
# ```ruby
|
||||
# desc "Open-source code editor"
|
||||
# ```
|
||||
#
|
||||
# @api public
|
||||
def desc(description = nil)
|
||||
set_unique_stanza(:desc, description.nil?) { description }
|
||||
@ -146,6 +164,14 @@ module Cask
|
||||
raise CaskInvalidError.new(cask, "'#{stanza}' stanza failed with: #{e}")
|
||||
end
|
||||
|
||||
# Sets the cask's homepage.
|
||||
#
|
||||
# ### Example
|
||||
#
|
||||
# ```ruby
|
||||
# homepage "https://code.visualstudio.com/"
|
||||
# ```
|
||||
#
|
||||
# @api public
|
||||
def homepage(homepage = nil)
|
||||
set_unique_stanza(:homepage, homepage.nil?) { homepage }
|
||||
@ -201,6 +227,14 @@ module Cask
|
||||
@language_blocks.keys.flatten
|
||||
end
|
||||
|
||||
# Sets the cask's download URL.
|
||||
#
|
||||
# ### Example
|
||||
#
|
||||
# ```ruby
|
||||
# url "https://update.code.visualstudio.com/#{version}/#{arch}/stable"
|
||||
# ```
|
||||
#
|
||||
# @api public
|
||||
def url(*args, **options, &block)
|
||||
caller_location = T.must(caller_locations).fetch(0)
|
||||
@ -214,6 +248,8 @@ module Cask
|
||||
end
|
||||
end
|
||||
|
||||
# Sets the cask's appcast URL.
|
||||
#
|
||||
# @api public
|
||||
def appcast(*args, **kwargs)
|
||||
set_unique_stanza(:appcast, args.empty? && kwargs.empty?) do
|
||||
@ -222,6 +258,22 @@ module Cask
|
||||
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
|
||||
def container(**kwargs)
|
||||
set_unique_stanza(:container, kwargs.empty?) do
|
||||
@ -229,6 +281,15 @@ module Cask
|
||||
end
|
||||
end
|
||||
|
||||
# Sets the cask's version.
|
||||
#
|
||||
# ### Example
|
||||
#
|
||||
# ```ruby
|
||||
# version "1.88.1"
|
||||
# ```
|
||||
#
|
||||
# @see DSL::Version
|
||||
# @api public
|
||||
def version(arg = nil)
|
||||
set_unique_stanza(:version, arg.nil?) do
|
||||
@ -240,6 +301,23 @@ module Cask
|
||||
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
|
||||
def sha256(arg = nil, arm: nil, intel: nil)
|
||||
should_return = arg.nil? && arm.nil? && intel.nil?
|
||||
@ -259,6 +337,14 @@ module Cask
|
||||
end
|
||||
end
|
||||
|
||||
# Sets the cask's architecture strings.
|
||||
#
|
||||
# ### Example
|
||||
#
|
||||
# ```ruby
|
||||
# arch arm: "darwin-arm64", intel: "darwin"
|
||||
# ```
|
||||
#
|
||||
# @api public
|
||||
def arch(arm: nil, intel: nil)
|
||||
should_return = arm.nil? && intel.nil?
|
||||
@ -270,7 +356,10 @@ module Cask
|
||||
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
|
||||
def depends_on(**kwargs)
|
||||
@depends_on ||= DSL::DependsOn.new
|
||||
@ -284,9 +373,11 @@ module Cask
|
||||
@depends_on
|
||||
end
|
||||
|
||||
# Declare conflicts that keep a cask from installing or working correctly.
|
||||
#
|
||||
# @api public
|
||||
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) }
|
||||
end
|
||||
|
||||
@ -298,6 +389,8 @@ module Cask
|
||||
cask.caskroom_path
|
||||
end
|
||||
|
||||
# The staged location for this cask, including version number.
|
||||
#
|
||||
# @api public
|
||||
def staged_path
|
||||
return @staged_path if @staged_path
|
||||
@ -306,6 +399,8 @@ module Cask
|
||||
@staged_path = caskroom_path.join(cask_version.to_s)
|
||||
end
|
||||
|
||||
# Provide the user with cask-specific information at install time.
|
||||
#
|
||||
# @api public
|
||||
def caveats(*strings, &block)
|
||||
@caveats ||= DSL::Caveats.new(cask)
|
||||
@ -326,11 +421,15 @@ module Cask
|
||||
@caveats&.discontinued? == true
|
||||
end
|
||||
|
||||
# Asserts that the cask artifacts auto-update.
|
||||
#
|
||||
# @api public
|
||||
def auto_updates(auto_updates = nil)
|
||||
set_unique_stanza(:auto_updates, auto_updates.nil?) { auto_updates }
|
||||
end
|
||||
|
||||
# Automatically fetch the latest version of a cask from changelogs.
|
||||
#
|
||||
# @api public
|
||||
def livecheck(&block)
|
||||
@livecheck ||= Livecheck.new(cask)
|
||||
@ -344,6 +443,10 @@ module Cask
|
||||
@livecheck.instance_eval(&block)
|
||||
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
|
||||
def deprecate!(date:, because:)
|
||||
@deprecation_date = Date.parse(date)
|
||||
@ -353,6 +456,10 @@ module Cask
|
||||
@deprecated = true
|
||||
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
|
||||
def disable!(date:, because:)
|
||||
@disable_date = Date.parse(date)
|
||||
@ -405,6 +512,8 @@ module Cask
|
||||
true
|
||||
end
|
||||
|
||||
# The directory `app`s are installed into.
|
||||
#
|
||||
# @api public
|
||||
def appdir
|
||||
return HOMEBREW_CASK_APPDIR_PLACEHOLDER if Cask.generating_hash?
|
||||
|
||||
@ -37,7 +37,6 @@ module Cask
|
||||
|
||||
private_class_method :caveat
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
(@custom_caveats + @built_in_caveats.values).join("\n")
|
||||
|
||||
@ -27,7 +27,6 @@ module Cask
|
||||
pairs.to_yaml
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s = pairs.inspect
|
||||
end
|
||||
|
||||
@ -9,8 +9,8 @@ module Cask
|
||||
class Postflight < Base
|
||||
include Staged
|
||||
|
||||
def suppress_move_to_applications(_options = {})
|
||||
odisabled "Cask::DSL#suppress_move_to_applications"
|
||||
def suppress_move_to_applications(**_options)
|
||||
odisabled "`Cask::DSL::Postflight#suppress_move_to_applications`"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -94,70 +94,94 @@ module Cask
|
||||
to_s == "latest"
|
||||
end
|
||||
|
||||
# The major version.
|
||||
#
|
||||
# @api public
|
||||
sig { returns(T.self_type) }
|
||||
def major
|
||||
version { slice(MAJOR_MINOR_PATCH_REGEX, 1) }
|
||||
end
|
||||
|
||||
# The minor version.
|
||||
#
|
||||
# @api public
|
||||
sig { returns(T.self_type) }
|
||||
def minor
|
||||
version { slice(MAJOR_MINOR_PATCH_REGEX, 2) }
|
||||
end
|
||||
|
||||
# The patch version.
|
||||
#
|
||||
# @api public
|
||||
sig { returns(T.self_type) }
|
||||
def patch
|
||||
version { slice(MAJOR_MINOR_PATCH_REGEX, 3) }
|
||||
end
|
||||
|
||||
# The major and minor version.
|
||||
#
|
||||
# @api public
|
||||
sig { returns(T.self_type) }
|
||||
def major_minor
|
||||
version { [major, minor].reject(&:empty?).join(".") }
|
||||
end
|
||||
|
||||
# The major, minor and patch version.
|
||||
#
|
||||
# @api public
|
||||
sig { returns(T.self_type) }
|
||||
def major_minor_patch
|
||||
version { [major, minor, patch].reject(&:empty?).join(".") }
|
||||
end
|
||||
|
||||
# The minor and patch version.
|
||||
#
|
||||
# @api public
|
||||
sig { returns(T.self_type) }
|
||||
def minor_patch
|
||||
version { [minor, patch].reject(&:empty?).join(".") }
|
||||
end
|
||||
|
||||
# The comma separated values of the version as array.
|
||||
#
|
||||
# @api public
|
||||
sig { returns(T::Array[Version]) } # Only top-level T.self_type is supported https://sorbet.org/docs/self-type
|
||||
def csv
|
||||
split(",").map { self.class.new(_1) }
|
||||
end
|
||||
|
||||
# The version part before the first comma.
|
||||
#
|
||||
# @api public
|
||||
sig { returns(T.self_type) }
|
||||
def before_comma
|
||||
version { split(",", 2).first }
|
||||
end
|
||||
|
||||
# The version part after the first comma.
|
||||
#
|
||||
# @api public
|
||||
sig { returns(T.self_type) }
|
||||
def after_comma
|
||||
version { split(",", 2).second }
|
||||
end
|
||||
|
||||
# The version without any dividers.
|
||||
#
|
||||
# @see DIVIDER_REGEX
|
||||
# @api public
|
||||
sig { returns(T.self_type) }
|
||||
def no_dividers
|
||||
version { gsub(DIVIDER_REGEX, "") }
|
||||
end
|
||||
|
||||
# The version with the given record separator removed from the end.
|
||||
#
|
||||
# @see String#chomp
|
||||
# @api public
|
||||
sig { params(separator: T.nilable(String)).returns(T.self_type) }
|
||||
def chomp(separator = nil)
|
||||
version { to_s.chomp(T.unsafe(separator)) }
|
||||
sig { params(separator: String).returns(T.self_type) }
|
||||
def chomp(separator = T.unsafe(nil))
|
||||
version { to_s.chomp(separator) }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@ -13,7 +13,6 @@ module Cask
|
||||
@errors = errors
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
<<~EOS
|
||||
@ -41,7 +40,6 @@ module Cask
|
||||
|
||||
# Error when a cask is not installed.
|
||||
class CaskNotInstalledError < AbstractCaskErrorWithToken
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
"Cask '#{token}' is not installed."
|
||||
@ -57,7 +55,6 @@ module Cask
|
||||
@message = message
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
"Cask '#{token}' has been #{message}"
|
||||
@ -73,7 +70,6 @@ module Cask
|
||||
@conflicting_cask = conflicting_cask
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
"Cask '#{token}' conflicts with '#{conflicting_cask}'."
|
||||
@ -82,7 +78,6 @@ module Cask
|
||||
|
||||
# Error when a cask is not available.
|
||||
class CaskUnavailableError < AbstractCaskErrorWithToken
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
"Cask '#{token}' is unavailable#{reason.empty? ? "." : ": #{reason}"}"
|
||||
@ -91,7 +86,6 @@ module Cask
|
||||
|
||||
# Error when a cask is unreadable.
|
||||
class CaskUnreadableError < CaskUnavailableError
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
"Cask '#{token}' is unreadable#{reason.empty? ? "." : ": #{reason}"}"
|
||||
@ -107,7 +101,6 @@ module Cask
|
||||
@tap = tap
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
s = super
|
||||
@ -142,7 +135,6 @@ module Cask
|
||||
|
||||
# Error when a cask already exists.
|
||||
class CaskAlreadyCreatedError < AbstractCaskErrorWithToken
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
%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.
|
||||
class CaskCyclicDependencyError < AbstractCaskErrorWithToken
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
"Cask '#{token}' includes cyclic dependencies on other Casks#{reason.empty? ? "." : ": #{reason}"}"
|
||||
@ -160,7 +151,6 @@ module Cask
|
||||
|
||||
# Error when a cask depends on itself.
|
||||
class CaskSelfReferencingDependencyError < CaskCyclicDependencyError
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
"Cask '#{token}' depends on itself."
|
||||
@ -169,7 +159,6 @@ module Cask
|
||||
|
||||
# Error when no cask is specified.
|
||||
class CaskUnspecifiedError < CaskError
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
"This command requires a Cask token."
|
||||
@ -178,7 +167,6 @@ module Cask
|
||||
|
||||
# Error when a cask is invalid.
|
||||
class CaskInvalidError < AbstractCaskErrorWithToken
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
"Cask '#{token}' definition is invalid#{reason.empty? ? "." : ": #{reason}"}"
|
||||
@ -203,7 +191,6 @@ module Cask
|
||||
@reason = reason
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
s = +"Failed to quarantine #{path}."
|
||||
@ -220,7 +207,6 @@ module Cask
|
||||
|
||||
# Error while propagating quarantine information to subdirectories.
|
||||
class CaskQuarantinePropagationError < CaskQuarantineError
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
s = +"Failed to quarantine one or more files within #{path}."
|
||||
@ -237,7 +223,6 @@ module Cask
|
||||
|
||||
# Error while removing quarantine information.
|
||||
class CaskQuarantineReleaseError < CaskQuarantineError
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
s = +"Failed to release #{path} from quarantine."
|
||||
|
||||
@ -17,22 +17,32 @@ module Cask
|
||||
extend Forwardable
|
||||
def_delegators :uri, :path, :scheme, :to_s
|
||||
|
||||
# @api public
|
||||
sig {
|
||||
params(
|
||||
uri: T.any(URI::Generic, String),
|
||||
# @api public
|
||||
verified: T.nilable(String),
|
||||
# @api public
|
||||
using: T.any(Class, Symbol, NilClass),
|
||||
# @api public
|
||||
tag: T.nilable(String),
|
||||
# @api public
|
||||
branch: T.nilable(String),
|
||||
# @api public
|
||||
revisions: T.nilable(T::Array[String]),
|
||||
# @api public
|
||||
revision: T.nilable(String),
|
||||
# @api public
|
||||
trust_cert: T.nilable(T::Boolean),
|
||||
# @api public
|
||||
cookies: T.nilable(T::Hash[String, String]),
|
||||
referer: T.nilable(T.any(URI::Generic, String)),
|
||||
# @api public
|
||||
header: T.nilable(T.any(String, T::Array[String])),
|
||||
user_agent: T.nilable(T.any(Symbol, String)),
|
||||
# @api public
|
||||
data: T.nilable(T::Hash[String, String]),
|
||||
# @api public
|
||||
only_path: T.nilable(String),
|
||||
).void
|
||||
}
|
||||
@ -77,8 +87,19 @@ module Cask
|
||||
end
|
||||
|
||||
class BlockDSL
|
||||
# To access URL associated with page contents.
|
||||
# Allow accessing the URL associated with page contents.
|
||||
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
|
||||
sig { returns(URI::Generic) }
|
||||
attr_accessor :url
|
||||
@ -87,12 +108,12 @@ module Cask
|
||||
sig {
|
||||
params(
|
||||
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))
|
||||
.returns(T.any(T.any(URI::Generic, String), [T.any(URI::Generic, String), Hash])),
|
||||
).void
|
||||
}
|
||||
def initialize(uri, dsl: nil, &block)
|
||||
def initialize(uri, dsl:, &block)
|
||||
@uri = uri
|
||||
@dsl = dsl
|
||||
@block = block
|
||||
@ -114,6 +135,8 @@ module Cask
|
||||
end
|
||||
end
|
||||
|
||||
# Allows calling a nested `url` stanza in a `url do` block.
|
||||
#
|
||||
# @api public
|
||||
sig {
|
||||
params(
|
||||
@ -123,10 +146,12 @@ module Cask
|
||||
).returns(T.any(T.any(URI::Generic, String), [T.any(URI::Generic, String), Hash]))
|
||||
}
|
||||
def url(uri, &block)
|
||||
self.class.new(uri, &block).call
|
||||
self.class.new(uri, dsl: @dsl, &block).call
|
||||
end
|
||||
private :url
|
||||
|
||||
# This allows calling DSL methods from inside a `url` block.
|
||||
#
|
||||
# @api public
|
||||
def method_missing(method, *args, &block)
|
||||
if @dsl.respond_to?(method)
|
||||
@ -135,10 +160,12 @@ module Cask
|
||||
super
|
||||
end
|
||||
end
|
||||
private :method_missing
|
||||
|
||||
def respond_to_missing?(method, include_all)
|
||||
@dsl.respond_to?(method, include_all) || super
|
||||
end
|
||||
private :respond_to_missing?
|
||||
end
|
||||
|
||||
sig {
|
||||
@ -187,7 +214,7 @@ module Cask
|
||||
super(
|
||||
if block
|
||||
LazyObject.new do
|
||||
uri2, options = *BlockDSL.new(uri, dsl:, &block).call
|
||||
uri2, options = *BlockDSL.new(uri, dsl: T.must(dsl), &block).call
|
||||
options ||= {}
|
||||
DSL.new(uri2, **options)
|
||||
end
|
||||
|
||||
@ -68,9 +68,9 @@ module Cask
|
||||
unless tried_permissions
|
||||
print_stderr = Context.current.debug? || Context.current.verbose?
|
||||
# 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
|
||||
# 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",
|
||||
print_stderr:,
|
||||
args: command_args + ["--", "000", path])
|
||||
@ -87,7 +87,7 @@ module Cask
|
||||
unless tried_ownership
|
||||
# in case of ownership problems
|
||||
# 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}'"
|
||||
command.run("/usr/sbin/chown",
|
||||
args: command_args + ["--", User.current, path],
|
||||
|
||||
@ -25,27 +25,28 @@ class Cleaner
|
||||
def clean
|
||||
ObserverPathnameExtension.reset_counts!
|
||||
|
||||
# Many formulae include 'lib/charset.alias', but it is not strictly needed
|
||||
# and will conflict if more than one formula provides it
|
||||
# Many formulae include `lib/charset.alias`, but it is not strictly needed
|
||||
# and will conflict if more than one formula provides it.
|
||||
observe_file_removal @formula.lib/"charset.alias"
|
||||
|
||||
[@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'
|
||||
# 2. 'info/#{name}/dir'
|
||||
# 3. 'info/#{arch}/dir'
|
||||
# 1. `info/dir`
|
||||
# 2. `info/#{name}/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.
|
||||
#
|
||||
# See [cleaner: recursively delete info `dir`s by gromgit · Pull Request
|
||||
# #11597][1], [emacs 28.1 bottle does not contain `dir` file · Issue
|
||||
# #100190][2], and [Keep `info/#{f.name}/dir` files in cleaner by
|
||||
# timvisher][3] for more info.
|
||||
# See
|
||||
# [cleaner: recursively delete info `dir`s][1],
|
||||
# [emacs 28.1 bottle does not contain `dir` file][2] and
|
||||
# [Keep `info/#{f.name}/dir` files in cleaner][3]
|
||||
# for more info.
|
||||
#
|
||||
# [1]: https://github.com/Homebrew/brew/pull/11597
|
||||
# [2]: https://github.com/Homebrew/homebrew-core/issues/100190
|
||||
@ -114,15 +115,15 @@ class Cleaner
|
||||
# created as part of installing any Perl module.
|
||||
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
|
||||
# directories) are protected by skip_clean.
|
||||
#
|
||||
# bin and sbin should not have any subdirectories; if either do that is
|
||||
# caught as an audit warning
|
||||
# `bin` and `sbin` should not have any subdirectories; if either do that is
|
||||
# caught as an audit warning.
|
||||
#
|
||||
# lib may have a large directory tree (see Erlang for instance), and
|
||||
# clean_dir applies cleaning rules to the entire tree
|
||||
# `lib` may have a large directory tree (see Erlang for instance) and
|
||||
# clean_dir applies cleaning rules to the entire tree.
|
||||
sig { params(directory: Pathname).void }
|
||||
def clean_dir(directory)
|
||||
directory.find do |path|
|
||||
@ -137,7 +138,7 @@ class Cleaner
|
||||
elsif path.symlink?
|
||||
# Skip it.
|
||||
else
|
||||
# Set permissions for executables and non-executables
|
||||
# Set permissions for executables and non-executables.
|
||||
perms = if executable_path?(path)
|
||||
0555
|
||||
else
|
||||
|
||||
@ -376,7 +376,7 @@ module Homebrew
|
||||
def cache_files
|
||||
files = cache.directory? ? cache.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 : []
|
||||
|
||||
files.map { |path| { path:, type: nil } } +
|
||||
@ -571,8 +571,8 @@ module Homebrew
|
||||
HOMEBREW_PREFIX.glob("lib/python*/site-packages").each do |site_packages|
|
||||
site_packages.each_child do |child|
|
||||
next unless child.directory?
|
||||
# TODO: Work out a sensible way to clean up pip's, setuptools', and wheel's
|
||||
# {dist,site}-info directories. Alternatively, consider always removing
|
||||
# TODO: Work out a sensible way to clean up `pip`'s, `setuptools`' and `wheel`'s
|
||||
# `{dist,site}-info` directories. Alternatively, consider always removing
|
||||
# all `-info` directories, because we may not be making use of them.
|
||||
next if child.basename.to_s.end_with?("-info")
|
||||
|
||||
|
||||
@ -95,7 +95,7 @@ module Homebrew
|
||||
dirs = HOMEBREW_PREFIX.subdirs.map { |dir| dir.basename.to_s }
|
||||
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|
|
||||
dirs.delete dir.relative_path_from(HOMEBREW_PREFIX).to_s
|
||||
end
|
||||
|
||||
@ -13,7 +13,7 @@ module Homebrew
|
||||
cmd_args do
|
||||
description <<~EOS
|
||||
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
|
||||
switch "-q", "--quiet",
|
||||
description: "List only the names of outdated kegs (takes precedence over `--verbose`)."
|
||||
|
||||
@ -756,7 +756,7 @@ class ReporterHub
|
||||
def dump(auto_update: false)
|
||||
report_all = ENV["HOMEBREW_UPDATE_REPORT_ALL_FORMULAE"].present?
|
||||
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."
|
||||
report_all = false
|
||||
end
|
||||
|
||||
@ -65,7 +65,6 @@ class CompilerFailure
|
||||
type == compiler.type && version_matched
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def inspect
|
||||
"#<#{self.class.name}: #{type} #{version}>"
|
||||
|
||||
@ -22,7 +22,6 @@ class CxxStdlib
|
||||
type.to_s.gsub(/cxx$/, "c++")
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def inspect
|
||||
"#<#{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? })
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def inspect
|
||||
"#<#{self.class.name}: #{__getobj__}>"
|
||||
@ -62,7 +61,6 @@ class Requirements < SimpleDelegator
|
||||
self
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def inspect
|
||||
"#<#{self.class.name}: {#{__getobj__.to_a.join(", ")}}>"
|
||||
|
||||
@ -33,7 +33,7 @@ module DependenciesHelpers
|
||||
end
|
||||
|
||||
# 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?
|
||||
end
|
||||
end
|
||||
|
||||
@ -4,6 +4,8 @@
|
||||
require "dependable"
|
||||
|
||||
# A dependency on another Homebrew formula.
|
||||
#
|
||||
# @api internal
|
||||
class Dependency
|
||||
extend Forwardable
|
||||
include Dependable
|
||||
@ -94,11 +96,9 @@ class Dependency
|
||||
false
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s = name
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def inspect
|
||||
"#<#{self.class.name}: #{name.inspect} #{tags.inspect}>"
|
||||
@ -115,6 +115,8 @@ class Dependency
|
||||
# the list.
|
||||
# The default filter, which is applied when a block is not given, omits
|
||||
# optionals and recommends based on what the dependent has asked for
|
||||
#
|
||||
# @api internal
|
||||
def expand(dependent, deps = dependent.deps, cache_key: nil, &block)
|
||||
# Keep track dependencies to avoid infinite cyclic dependency recursion.
|
||||
@expand_stack ||= []
|
||||
@ -181,6 +183,8 @@ class Dependency
|
||||
end
|
||||
|
||||
# Keep a dependency, but prune its dependencies.
|
||||
#
|
||||
# @api internal
|
||||
sig { void }
|
||||
def 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:)
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def inspect
|
||||
"#<#{self.class.name}: #{name.inspect} #{tags.inspect} #{bounds.inspect}>"
|
||||
|
||||
@ -7,13 +7,13 @@ require "requirement"
|
||||
require "requirements"
|
||||
require "extend/cachable"
|
||||
|
||||
## A dependency is a formula that another formula needs to install.
|
||||
## A requirement is something other than a formula that another formula
|
||||
## needs to be present. This includes external language modules,
|
||||
## command-line tools in the path, or any arbitrary predicate.
|
||||
##
|
||||
## The `depends_on` method in the formula DSL is used to declare
|
||||
## dependencies and requirements.
|
||||
# A dependency is a formula that another formula needs to install.
|
||||
# A requirement is something other than a formula that another formula
|
||||
# needs to be present. This includes external language modules,
|
||||
# command-line tools in the path, or any arbitrary predicate.
|
||||
#
|
||||
# The `depends_on` method in the formula DSL is used to declare
|
||||
# dependencies and requirements.
|
||||
|
||||
# This class is used by `depends_on` in the formula DSL to turn dependency
|
||||
# specifications into the proper kinds of dependencies and requirements.
|
||||
|
||||
@ -98,7 +98,7 @@ module Homebrew
|
||||
end
|
||||
odie "Could not find #{name}! The formula or version may not have existed." if test_formula.nil?
|
||||
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|
|
||||
Pathname.glob("#{dir}/#{name}.rb").find(&:file?)
|
||||
end
|
||||
|
||||
@ -15,7 +15,7 @@ module Homebrew
|
||||
|
||||
cmd_args do
|
||||
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.
|
||||
Requires write access to the repository.
|
||||
EOS
|
||||
@ -187,7 +187,7 @@ module Homebrew
|
||||
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)
|
||||
subject = message.lines.first.strip
|
||||
|
||||
@ -337,7 +337,7 @@ module Homebrew
|
||||
new_package = package_file.read
|
||||
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",
|
||||
"-m", bump_subject, "-m", messages.join("\n"), "-m", trailers.join("\n"),
|
||||
"--author", original_author, "--date", original_date, "--", file)
|
||||
|
||||
@ -20,16 +20,18 @@ module Homebrew
|
||||
def run
|
||||
Homebrew.install_bundler_gems!(groups: ["doc"])
|
||||
|
||||
HOMEBREW_LIBRARY_PATH.cd do
|
||||
HOMEBREW_LIBRARY_PATH.cd do |dir|
|
||||
no_api_args = if args.only_public?
|
||||
["--hide-api", "private", "--hide-api", "internal"]
|
||||
else
|
||||
[]
|
||||
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
|
||||
|
||||
@ -46,6 +46,8 @@ module Homebrew
|
||||
|
||||
(tap.path/"Formula").mkpath
|
||||
|
||||
# FIXME: https://github.com/errata-ai/vale/issues/818
|
||||
# <!-- vale off -->
|
||||
readme = <<~MARKDOWN
|
||||
# #{titleized_user} #{titleized_repo}
|
||||
|
||||
@ -59,6 +61,7 @@ module Homebrew
|
||||
|
||||
`brew help`, `man brew` or check [Homebrew's documentation](https://docs.brew.sh).
|
||||
MARKDOWN
|
||||
# <!-- vale on -->
|
||||
write_path(tap, "README.md", readme)
|
||||
|
||||
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 " \
|
||||
"official external commands."
|
||||
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",
|
||||
description: "Only runs tests on files that were changed from the master branch."
|
||||
switch "--fail-fast",
|
||||
description: "Exit early on the first failing test."
|
||||
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."
|
||||
flag "--profile=",
|
||||
description: "Run the test suite serially to find the <n> slowest tests."
|
||||
@ -145,7 +145,10 @@ module Homebrew
|
||||
end
|
||||
|
||||
# Workaround for:
|
||||
#
|
||||
# ```
|
||||
# ruby: no -r allowed while running setuid (SecurityError)
|
||||
# ```
|
||||
Process::UID.change_privilege(Process.euid) if Process.euid != Process.uid
|
||||
|
||||
if parallel
|
||||
|
||||
@ -116,7 +116,7 @@ module Homebrew
|
||||
# update ENV["PATH"]
|
||||
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"
|
||||
|
||||
# run brew update
|
||||
|
||||
@ -221,7 +221,7 @@ module Homebrew
|
||||
__check_stray_files "/usr/local/lib", "*.dylib", allow_list, <<~EOS
|
||||
Unbrewed dylibs were found in /usr/local/lib.
|
||||
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:
|
||||
EOS
|
||||
@ -246,7 +246,7 @@ module Homebrew
|
||||
__check_stray_files "/usr/local/lib", "*.a", allow_list, <<~EOS
|
||||
Unbrewed static libraries were found in /usr/local/lib.
|
||||
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:
|
||||
EOS
|
||||
@ -266,7 +266,7 @@ module Homebrew
|
||||
__check_stray_files "/usr/local/lib/pkgconfig", "*.pc", allow_list, <<~EOS
|
||||
Unbrewed '.pc' files were found in /usr/local/lib/pkgconfig.
|
||||
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:
|
||||
EOS
|
||||
@ -287,7 +287,7 @@ module Homebrew
|
||||
__check_stray_files "/usr/local/lib", "*.la", allow_list, <<~EOS
|
||||
Unbrewed '.la' files were found in /usr/local/lib.
|
||||
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:
|
||||
EOS
|
||||
@ -306,7 +306,7 @@ module Homebrew
|
||||
__check_stray_files "/usr/local/include", "**/*.h", allow_list, <<~EOS
|
||||
Unbrewed header files were found in /usr/local/include.
|
||||
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:
|
||||
EOS
|
||||
@ -491,7 +491,7 @@ module Homebrew
|
||||
|
||||
<<~EOS
|
||||
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:
|
||||
brew install git
|
||||
EOS
|
||||
|
||||
@ -77,11 +77,9 @@ class AbstractDownloadStrategy
|
||||
end
|
||||
|
||||
# Disable any output during downloading.
|
||||
#
|
||||
# @deprecated
|
||||
sig { void }
|
||||
def shutup!
|
||||
odeprecated "AbstractDownloadStrategy#shutup!", "AbstractDownloadStrategy#quiet!"
|
||||
odeprecated "`AbstractDownloadStrategy#shutup!`", "`AbstractDownloadStrategy#quiet!`"
|
||||
quiet!
|
||||
end
|
||||
|
||||
@ -125,7 +123,6 @@ class AbstractDownloadStrategy
|
||||
end
|
||||
private :chdir
|
||||
|
||||
# @!attribute [r] source_modified_time
|
||||
# Returns the most recent modified time for all files in the current working directory after stage.
|
||||
#
|
||||
# @api public
|
||||
@ -236,9 +233,7 @@ class VCSDownloadStrategy < AbstractDownloadStrategy
|
||||
version.respond_to?(:head?) && version.head?
|
||||
end
|
||||
|
||||
# @!attribute [r] last_commit
|
||||
# Return last commit's unique identifier for the repository.
|
||||
# Return most recent modified timestamp unless overridden.
|
||||
# Return the most recent modified timestamp.
|
||||
#
|
||||
# @api public
|
||||
sig { returns(String) }
|
||||
@ -733,7 +728,8 @@ class SubversionDownloadStrategy < VCSDownloadStrategy
|
||||
super
|
||||
end
|
||||
|
||||
# @see AbstractDownloadStrategy#source_modified_time
|
||||
# Returns the most recent modified time for all files in the current working directory after stage.
|
||||
#
|
||||
# @api public
|
||||
sig { returns(Time) }
|
||||
def source_modified_time
|
||||
@ -747,7 +743,8 @@ class SubversionDownloadStrategy < VCSDownloadStrategy
|
||||
Time.parse time
|
||||
end
|
||||
|
||||
# @see VCSDownloadStrategy#last_commit
|
||||
# Return last commit's unique identifier for the repository.
|
||||
#
|
||||
# @api public
|
||||
sig { returns(String) }
|
||||
def last_commit
|
||||
@ -847,7 +844,8 @@ class GitDownloadStrategy < VCSDownloadStrategy
|
||||
@ref ||= "master"
|
||||
end
|
||||
|
||||
# @see AbstractDownloadStrategy#source_modified_time
|
||||
# Returns the most recent modified time for all files in the current working directory after stage.
|
||||
#
|
||||
# @api public
|
||||
sig { returns(Time) }
|
||||
def source_modified_time
|
||||
@ -855,7 +853,8 @@ class GitDownloadStrategy < VCSDownloadStrategy
|
||||
Time.parse(out)
|
||||
end
|
||||
|
||||
# @see VCSDownloadStrategy#last_commit
|
||||
# Return last commit's unique identifier for the repository.
|
||||
#
|
||||
# @api public
|
||||
sig { returns(String) }
|
||||
def last_commit
|
||||
@ -932,8 +931,8 @@ class GitDownloadStrategy < VCSDownloadStrategy
|
||||
|
||||
args << "--no-checkout" << "--filter=blob:none" if partial_clone_sparse_checkout?
|
||||
|
||||
args << "--config" << "advice.detachedHead=false" # silences detached head warning
|
||||
args << "--config" << "core.fsmonitor=false" # prevent fsmonitor from watching this repo
|
||||
args << "--config" << "advice.detachedHead=false" # Silences “detached head” warning.
|
||||
args << "--config" << "core.fsmonitor=false" # Prevent `fsmonitor` from watching this repository.
|
||||
args << @url << cached_location.to_s
|
||||
end
|
||||
|
||||
@ -1165,7 +1164,8 @@ class CVSDownloadStrategy < VCSDownloadStrategy
|
||||
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
|
||||
sig { returns(Time) }
|
||||
def source_modified_time
|
||||
@ -1240,7 +1240,8 @@ class MercurialDownloadStrategy < VCSDownloadStrategy
|
||||
@url = @url.sub(%r{^hg://}, "")
|
||||
end
|
||||
|
||||
# @see AbstractDownloadStrategy#source_modified_time
|
||||
# Returns the most recent modified time for all files in the current working directory after stage.
|
||||
#
|
||||
# @api public
|
||||
sig { returns(Time) }
|
||||
def source_modified_time
|
||||
@ -1250,7 +1251,8 @@ class MercurialDownloadStrategy < VCSDownloadStrategy
|
||||
Time.parse(out)
|
||||
end
|
||||
|
||||
# @see VCSDownloadStrategy#last_commit
|
||||
# Return last commit's unique identifier for the repository.
|
||||
#
|
||||
# @api public
|
||||
sig { returns(String) }
|
||||
def last_commit
|
||||
@ -1327,7 +1329,8 @@ class BazaarDownloadStrategy < VCSDownloadStrategy
|
||||
@url = @url.sub(%r{^bzr://}, "")
|
||||
end
|
||||
|
||||
# @see AbstractDownloadStrategy#source_modified_time
|
||||
# Returns the most recent modified time for all files in the current working directory after stage.
|
||||
#
|
||||
# @api public
|
||||
sig { returns(Time) }
|
||||
def source_modified_time
|
||||
@ -1338,7 +1341,8 @@ class BazaarDownloadStrategy < VCSDownloadStrategy
|
||||
Time.parse(timestamp)
|
||||
end
|
||||
|
||||
# @see VCSDownloadStrategy#last_commit
|
||||
# Return last commit's unique identifier for the repository.
|
||||
#
|
||||
# @api public
|
||||
sig { returns(String) }
|
||||
def last_commit
|
||||
@ -1390,7 +1394,8 @@ class FossilDownloadStrategy < VCSDownloadStrategy
|
||||
@url = @url.sub(%r{^fossil://}, "")
|
||||
end
|
||||
|
||||
# @see AbstractDownloadStrategy#source_modified_time
|
||||
# Returns the most recent modified time for all files in the current working directory after stage.
|
||||
#
|
||||
# @api public
|
||||
sig { returns(Time) }
|
||||
def source_modified_time
|
||||
@ -1398,7 +1403,8 @@ class FossilDownloadStrategy < VCSDownloadStrategy
|
||||
Time.parse(out[/^uuid: +\h+ (.+)$/, 1])
|
||||
end
|
||||
|
||||
# @see VCSDownloadStrategy#last_commit
|
||||
# Return last commit's unique identifier for the repository.
|
||||
#
|
||||
# @api public
|
||||
sig { returns(String) }
|
||||
def last_commit
|
||||
|
||||
@ -16,7 +16,6 @@ class UsageError < RuntimeError
|
||||
@reason = reason
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
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 "}?"
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
s = "No available formula or cask with the name \"#{name}\". #{did_you_mean}".strip
|
||||
@ -129,7 +127,6 @@ class TapFormulaOrCaskUnavailableError < FormulaOrCaskUnavailableError
|
||||
@tap = tap
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
s = super
|
||||
@ -149,7 +146,6 @@ class FormulaUnavailableError < FormulaOrCaskUnavailableError
|
||||
" (dependency of #{dependent})" if dependent && dependent != name
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
"No available formula with the name \"#{name}\"#{dependent_s}. #{did_you_mean}".strip
|
||||
@ -160,7 +156,6 @@ end
|
||||
module FormulaClassUnavailableErrorModule
|
||||
attr_reader :path, :class_name, :class_list
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
s = super
|
||||
@ -204,7 +199,6 @@ end
|
||||
module FormulaUnreadableErrorModule
|
||||
attr_reader :formula_error
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
"#{name}: " + formula_error.to_s
|
||||
@ -233,7 +227,6 @@ class TapFormulaUnavailableError < FormulaUnavailableError
|
||||
super "#{tap}/#{name}"
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
s = super
|
||||
@ -572,7 +565,7 @@ class UnbottledError < RuntimeError
|
||||
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
|
||||
# installation on a system without build tools to fail.
|
||||
class BuildFlagsError < RuntimeError
|
||||
|
||||
@ -17,10 +17,16 @@ module Kernel
|
||||
private :superenv?
|
||||
end
|
||||
|
||||
# <!-- vale off -->
|
||||
# @!parse
|
||||
# # ENV is not actually a class, but this makes `YARD` happy
|
||||
# # @see https://rubydoc.info/stdlib/core/ENV ENV core documentation
|
||||
# class ENV; end
|
||||
# # `ENV` is not actually a class, but this makes YARD happy
|
||||
# # @see https://rubydoc.info/stdlib/core/ENV
|
||||
# # <code>ENV</code> core documentation
|
||||
# # @see Superenv
|
||||
# # @see Stdenv
|
||||
# class ENV; end
|
||||
# <!-- vale on -->
|
||||
|
||||
module EnvActivation
|
||||
sig { params(env: T.nilable(String)).void }
|
||||
def activate_extensions!(env: nil)
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
# typed: strict
|
||||
|
||||
# @!visibility private
|
||||
module EnvMethods
|
||||
include Kernel
|
||||
|
||||
@ -39,6 +40,7 @@ module EnvActivation
|
||||
include Superenv
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
class Sorbet
|
||||
module Private
|
||||
module Static
|
||||
|
||||
@ -4,6 +4,7 @@ module SharedEnvExtension
|
||||
include EnvMethods
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
class Sorbet
|
||||
module Private
|
||||
module Static
|
||||
|
||||
@ -2,59 +2,72 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
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]
|
||||
|
||||
# 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]
|
||||
|
||||
# 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]
|
||||
|
||||
# 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]
|
||||
|
||||
# Converts the array to a comma-separated sentence where the last element is
|
||||
# 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
|
||||
# element in arrays with three or more elements (default: ", ").
|
||||
# * <tt>:last_word_connector</tt> - The sign or word used to join the last element
|
||||
# in arrays with three or more elements (default: ", and ").
|
||||
# * <tt>:two_words_connector</tt> - The sign or word used to join the elements
|
||||
# in arrays with two elements (default: " and ").
|
||||
# ```ruby
|
||||
# [].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"
|
||||
# ```
|
||||
#
|
||||
# ==== 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
|
||||
# ActiveSupport Array#to_sentence monkey-patch
|
||||
#
|
||||
#
|
||||
# Copyright (c) David Heinemeier Hansson
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# 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
|
||||
# the following conditions:
|
||||
#
|
||||
@ -68,6 +81,14 @@ class Array
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# 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) }
|
||||
def to_sentence(words_connector: ", ", two_words_connector: " and ", last_word_connector: " and ")
|
||||
case length
|
||||
|
||||
@ -3,15 +3,20 @@
|
||||
|
||||
class Object
|
||||
# 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) }
|
||||
def blank?
|
||||
respond_to?(:empty?) ? !!T.unsafe(self).empty? : false
|
||||
@ -21,20 +26,23 @@ class Object
|
||||
sig { returns(T::Boolean) }
|
||||
def present? = !blank?
|
||||
|
||||
# Returns the receiver if it's present otherwise returns +nil+.
|
||||
# <tt>object.presence</tt> is equivalent to
|
||||
# Returns the receiver if it's present, otherwise returns `nil`.
|
||||
#
|
||||
# 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?
|
||||
# country = params[:country] if params[:country].present?
|
||||
# region = state || country || 'US'
|
||||
# ```ruby
|
||||
# state = params[:state] if params[:state].present?
|
||||
# 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)) }
|
||||
def presence
|
||||
self if present?
|
||||
@ -42,9 +50,11 @@ class Object
|
||||
end
|
||||
|
||||
class NilClass
|
||||
# +nil+ is blank:
|
||||
# `nil` is blank:
|
||||
#
|
||||
# nil.blank? # => true
|
||||
# ```ruby
|
||||
# nil.blank? # => true
|
||||
# ```
|
||||
sig { returns(TrueClass) }
|
||||
def blank? = true
|
||||
|
||||
@ -53,9 +63,11 @@ class NilClass
|
||||
end
|
||||
|
||||
class FalseClass
|
||||
# +false+ is blank:
|
||||
# `false` is blank:
|
||||
#
|
||||
# false.blank? # => true
|
||||
# ```ruby
|
||||
# false.blank? # => true
|
||||
# ```
|
||||
sig { returns(TrueClass) }
|
||||
def blank? = true
|
||||
|
||||
@ -64,9 +76,11 @@ class FalseClass
|
||||
end
|
||||
|
||||
class TrueClass
|
||||
# +true+ is not blank:
|
||||
# `true` is not blank:
|
||||
#
|
||||
# true.blank? # => false
|
||||
# ```ruby
|
||||
# true.blank? # => false
|
||||
# ```
|
||||
sig { returns(FalseClass) }
|
||||
def blank? = false
|
||||
|
||||
@ -77,11 +91,12 @@ end
|
||||
class Array
|
||||
# An array is blank if it's empty:
|
||||
#
|
||||
# [].blank? # => true
|
||||
# [1,2,3].blank? # => false
|
||||
#
|
||||
# @return [true, false]
|
||||
alias blank? empty?
|
||||
# ```ruby
|
||||
# [].blank? # => true
|
||||
# [1,2,3].blank? # => false
|
||||
# ```
|
||||
sig { returns(T::Boolean) }
|
||||
def blank? = empty?
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def present? = !empty? # :nodoc:
|
||||
@ -90,11 +105,13 @@ end
|
||||
class Hash
|
||||
# A hash is blank if it's empty:
|
||||
#
|
||||
# {}.blank? # => true
|
||||
# { key: 'value' }.blank? # => false
|
||||
#
|
||||
# @return [true, false]
|
||||
alias blank? empty?
|
||||
# ```ruby
|
||||
# {}.blank? # => true
|
||||
# { key: 'value' }.blank? # => false
|
||||
# ```
|
||||
sig { returns(T::Boolean) }
|
||||
def blank? = empty?
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def present? = !empty? # :nodoc:
|
||||
@ -103,9 +120,12 @@ end
|
||||
class Symbol
|
||||
# A Symbol is blank if it's empty:
|
||||
#
|
||||
# :''.blank? # => true
|
||||
# :symbol.blank? # => false
|
||||
alias blank? empty?
|
||||
# ```ruby
|
||||
# :''.blank? # => true
|
||||
# :symbol.blank? # => false
|
||||
# ```
|
||||
sig { returns(T::Boolean) }
|
||||
def blank? = empty?
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def present? = !empty? # :nodoc:
|
||||
@ -122,14 +142,18 @@ class String
|
||||
|
||||
# A string is blank if it's empty or contains whitespaces only:
|
||||
#
|
||||
# ''.blank? # => true
|
||||
# ' '.blank? # => true
|
||||
# "\t\n\r".blank? # => true
|
||||
# ' blah '.blank? # => false
|
||||
# ```ruby
|
||||
# ''.blank? # => true
|
||||
# ' '.blank? # => true
|
||||
# "\t\n\r".blank? # => true
|
||||
# ' blah '.blank? # => false
|
||||
# ```
|
||||
#
|
||||
# Unicode whitespace is supported:
|
||||
#
|
||||
# "\u00a0".blank? # => true
|
||||
# ```ruby
|
||||
# "\u00a0".blank? # => true
|
||||
# ```
|
||||
sig { returns(T::Boolean) }
|
||||
def blank?
|
||||
# The regexp that matches blank strings is expensive. For the case of empty
|
||||
@ -150,8 +174,10 @@ end
|
||||
class Numeric # :nodoc:
|
||||
# No number is blank:
|
||||
#
|
||||
# 1.blank? # => false
|
||||
# 0.blank? # => false
|
||||
# ```ruby
|
||||
# 1.blank? # => false
|
||||
# 0.blank? # => false
|
||||
# ```
|
||||
sig { returns(FalseClass) }
|
||||
def blank? = false
|
||||
|
||||
@ -162,7 +188,9 @@ end
|
||||
class Time # :nodoc:
|
||||
# No Time is blank:
|
||||
#
|
||||
# Time.now.blank? # => false
|
||||
# ```ruby
|
||||
# Time.now.blank? # => false
|
||||
# ```
|
||||
sig { returns(FalseClass) }
|
||||
def blank? = false
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
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.
|
||||
sig { params(object: T.untyped).returns(T::Boolean) }
|
||||
def exclude?(object) = !include?(object)
|
||||
@ -10,21 +10,29 @@ module Enumerable
|
||||
# Returns a new +Array+ without the blank items.
|
||||
# Uses Object#blank? for determining if an item is blank.
|
||||
#
|
||||
# [1, "", nil, 2, " ", [], {}, false, true].compact_blank
|
||||
# # => [1, 2, true]
|
||||
# ### Examples
|
||||
#
|
||||
# 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
|
||||
# # => { b: 1, f: true }
|
||||
# When called on a {Hash}, returns a new {Hash} without the blank values.
|
||||
#
|
||||
# ```ruby
|
||||
# { a: "", b: 1, c: nil, d: [], e: false, f: true }.compact_blank
|
||||
# # => { b: 1, f: true }
|
||||
# ```
|
||||
sig { returns(T.self_type) }
|
||||
def compact_blank = T.unsafe(self).reject(&:blank?)
|
||||
end
|
||||
|
||||
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? }
|
||||
end
|
||||
|
||||
@ -2,25 +2,31 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
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] } }
|
||||
# h2 = { a: false, b: { x: [3, 4, 5] } }
|
||||
# ### Examples
|
||||
#
|
||||
# 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
|
||||
# to merge values:
|
||||
#
|
||||
# h1 = { a: 100, b: 200, c: { c1: 100 } }
|
||||
# h2 = { b: 250, c: { c1: 200 } }
|
||||
# h1.deep_merge(h2) { |key, this_val, other_val| this_val + other_val }
|
||||
# # => { a: 100, b: 450, c: { c1: 300 } }
|
||||
# ```ruby
|
||||
# h1 = { a: 100, b: 200, c: { c1: 100 } }
|
||||
# h2 = { b: 250, c: { c1: 200 } }
|
||||
# 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)
|
||||
dup.deep_merge!(other_hash, &block)
|
||||
end
|
||||
|
||||
# Same as +deep_merge+, but modifies +self+.
|
||||
# Same as {#deep_merge}, but modifies `self`.
|
||||
def deep_merge!(other_hash, &block)
|
||||
merge!(other_hash) do |key, this_val, other_val|
|
||||
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
|
||||
# nested hashes and arrays.
|
||||
#
|
||||
# @example
|
||||
# hash = { person: { name: 'Rob', age: '28' } }
|
||||
# ### Example
|
||||
#
|
||||
# hash.deep_transform_values{ |value| value.to_s.upcase }
|
||||
# # => {person: {name: "ROB", age: "28"}}
|
||||
# ```ruby
|
||||
# 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)
|
||||
|
||||
# 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
|
||||
# `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.
|
||||
#
|
||||
# { name: 'Rob', years: '28' }.assert_valid_keys(:name, :age)
|
||||
# # => 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
|
||||
# ### Example#
|
||||
#
|
||||
# ```ruby
|
||||
# { name: 'Rob', years: '28' }.assert_valid_keys(:name, :age)
|
||||
# # => 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 }
|
||||
def assert_valid_keys(*valid_keys)
|
||||
valid_keys.flatten!
|
||||
@ -28,10 +32,14 @@ class Hash
|
||||
# This includes the keys from the root hash and from all
|
||||
# nested hashes and arrays.
|
||||
#
|
||||
# hash = { person: { name: 'Rob', age: '28' } }
|
||||
# ### Example
|
||||
#
|
||||
# hash.deep_transform_keys{ |key| key.to_s.upcase }
|
||||
# # => {"PERSON"=>{"NAME"=>"Rob", "AGE"=>"28"}}
|
||||
# ```ruby
|
||||
# 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)
|
||||
|
||||
# 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
|
||||
# nested hashes and arrays.
|
||||
#
|
||||
# hash = { person: { name: 'Rob', age: '28' } }
|
||||
# ### Example
|
||||
#
|
||||
# hash.deep_stringify_keys
|
||||
# # => {"person"=>{"name"=>"Rob", "age"=>"28"}}
|
||||
# ```ruby
|
||||
# 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)
|
||||
|
||||
# Destructively converts all keys to strings.
|
||||
@ -55,13 +67,17 @@ class Hash
|
||||
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
|
||||
# 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.
|
||||
#
|
||||
# hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } }
|
||||
# ### Example
|
||||
#
|
||||
# hash.deep_symbolize_keys
|
||||
# # => {:person=>{:name=>"Rob", :age=>"28"}}
|
||||
# ```ruby
|
||||
# hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } }
|
||||
#
|
||||
# hash.deep_symbolize_keys
|
||||
# # => {:person=>{:name=>"Rob", :age=>"28"}}
|
||||
# ```
|
||||
def deep_symbolize_keys
|
||||
deep_transform_keys do |key|
|
||||
T.unsafe(key).to_sym
|
||||
@ -71,7 +87,7 @@ class Hash
|
||||
end
|
||||
|
||||
# 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.
|
||||
def deep_symbolize_keys!
|
||||
deep_transform_keys! do |key|
|
||||
@ -102,7 +118,7 @@ class Hash
|
||||
def _deep_transform_keys_in_object!(object, &block)
|
||||
case object
|
||||
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
|
||||
value = object.delete(key)
|
||||
object[yield(key)] = _deep_transform_keys_in_object!(value, &block)
|
||||
|
||||
@ -493,14 +493,20 @@ module Kernel
|
||||
end
|
||||
|
||||
# Calls the given block with the passed environment variables
|
||||
# added to ENV, then restores ENV afterwards.
|
||||
# <pre>with_env(PATH: "/bin") do
|
||||
# system "echo $PATH"
|
||||
# end</pre>
|
||||
# added to `ENV`, then restores `ENV` afterwards.
|
||||
#
|
||||
# NOTE: This method is **not** thread-safe – other threads
|
||||
# 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
|
||||
def with_env(hash)
|
||||
old_values = {}
|
||||
|
||||
@ -1,24 +1,30 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
#--
|
||||
# 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+
|
||||
# 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:
|
||||
#
|
||||
# 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.
|
||||
# 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.
|
||||
#
|
||||
# That's why we hardcode the following cases and check duplicable? instead of
|
||||
# using that rescue idiom.
|
||||
#++
|
||||
# rubocop:disable Layout/EmptyLines
|
||||
|
||||
|
||||
# rubocop:enable Layout/EmptyLines
|
||||
class Object
|
||||
# Can you safely dup this object?
|
||||
#
|
||||
@ -31,8 +37,10 @@ end
|
||||
class Method
|
||||
# Methods are not duplicable:
|
||||
#
|
||||
# method(:puts).duplicable? # => false
|
||||
# method(:puts).dup # => TypeError: allocator undefined for Method
|
||||
# ```ruby
|
||||
# method(:puts).duplicable? # => false
|
||||
# method(:puts).dup # => TypeError: allocator undefined for Method
|
||||
# ```
|
||||
sig { returns(FalseClass) }
|
||||
def duplicable? = false
|
||||
end
|
||||
@ -40,8 +48,10 @@ end
|
||||
class UnboundMethod
|
||||
# Unbound methods are not duplicable:
|
||||
#
|
||||
# method(:puts).unbind.duplicable? # => false
|
||||
# method(:puts).unbind.dup # => TypeError: allocator undefined for UnboundMethod
|
||||
# ```ruby
|
||||
# method(:puts).unbind.duplicable? # => false
|
||||
# method(:puts).unbind.dup # => TypeError: allocator undefined for UnboundMethod
|
||||
# ```
|
||||
sig { returns(FalseClass) }
|
||||
def duplicable? = false
|
||||
end
|
||||
@ -51,7 +61,9 @@ require "singleton"
|
||||
module Singleton
|
||||
# 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) }
|
||||
def duplicable? = false
|
||||
end
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
module Homebrew
|
||||
module Install
|
||||
# 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.
|
||||
DYNAMIC_LINKERS = %w[
|
||||
/lib64/ld-linux-x86-64.so.2
|
||||
@ -19,7 +19,7 @@ module Homebrew
|
||||
private_constant :DYNAMIC_LINKERS
|
||||
|
||||
# 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
|
||||
# GCC can find its own libraries.
|
||||
GCC_RUNTIME_LIBS = %w[
|
||||
|
||||
@ -16,7 +16,7 @@ module Homebrew
|
||||
return unless @args.cask?
|
||||
|
||||
# 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"
|
||||
end
|
||||
end
|
||||
|
||||
@ -340,7 +340,7 @@ module Homebrew
|
||||
else
|
||||
inject_file_list @found, <<~EOS
|
||||
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
|
||||
compile or link failure, especially if compiled with improper
|
||||
architectures. macOS itself never installs anything to /usr/local so
|
||||
|
||||
@ -27,12 +27,11 @@ module Stdenv
|
||||
|
||||
append "LDFLAGS", "-Wl,-headerpad_max_install_names"
|
||||
|
||||
# sed is strict, and errors out when it encounters files with
|
||||
# mixed character sets
|
||||
# `sed` is strict and errors out when it encounters files with mixed character sets.
|
||||
delete("LC_ALL")
|
||||
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:)
|
||||
|
||||
return unless MacOS::Xcode.without_clt?
|
||||
@ -42,8 +41,8 @@ module Stdenv
|
||||
end
|
||||
|
||||
def remove_macosxsdk(version = nil)
|
||||
# Clear all lib and include dirs from CFLAGS, CPPFLAGS, LDFLAGS that were
|
||||
# previously added by macosxsdk
|
||||
# Clear all `lib` and `include` dirs from `CFLAGS`, `CPPFLAGS`, `LDFLAGS` that were
|
||||
# previously added by `macosxsdk`.
|
||||
remove_from_cflags(/ ?-mmacosx-version-min=\d+\.\d+/)
|
||||
delete("CPATH")
|
||||
remove "LDFLAGS", "-L#{HOMEBREW_PREFIX}/lib"
|
||||
@ -58,14 +57,14 @@ module Stdenv
|
||||
if HOMEBREW_PREFIX.to_s == "/usr/local"
|
||||
delete("CMAKE_PREFIX_PATH")
|
||||
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
|
||||
end
|
||||
remove "CMAKE_FRAMEWORK_PATH", "#{sdk}/System/Library/Frameworks"
|
||||
end
|
||||
|
||||
def macosxsdk(version = nil, formula: nil, testing_formula: false)
|
||||
# Sets all needed lib and include dirs to CFLAGS, CPPFLAGS, LDFLAGS.
|
||||
# Sets all needed `lib` and `include` dirs to `CFLAGS`, `CPPFLAGS`, `LDFLAGS`.
|
||||
remove_macosxsdk
|
||||
min_version = version || MacOS.version
|
||||
append_to_cflags("-mmacosx-version-min=#{min_version}")
|
||||
|
||||
@ -112,7 +112,7 @@ module FormulaCellarChecks
|
||||
|
||||
<<~EOS
|
||||
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.
|
||||
#{flat_namespace_files * "\n "}
|
||||
EOS
|
||||
|
||||
@ -83,8 +83,8 @@ module Hardware
|
||||
sysctl_bool("hw.optional.sse4_2")
|
||||
end
|
||||
|
||||
# NOTE: this is more reliable than checking uname.
|
||||
# `sysctl` returns the right answer even when running in Rosetta 2.
|
||||
# NOTE: This is more reliable than checking `uname`. `sysctl` returns
|
||||
# the right answer even when running in Rosetta 2.
|
||||
def physical_cpu_arm64?
|
||||
sysctl_bool("hw.optional.arm64")
|
||||
end
|
||||
|
||||
@ -126,10 +126,11 @@ class Pathname
|
||||
|
||||
mkpath
|
||||
|
||||
# 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:
|
||||
# https://bugs.ruby-lang.org/issues/7707
|
||||
# In that case, use the system "mv" command.
|
||||
# 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
|
||||
# (https://bugs.ruby-lang.org/issues/7707).
|
||||
#
|
||||
# In that case, use the system `mv` command.
|
||||
if src.symlink?
|
||||
raise unless Kernel.system "mv", src.to_s, dst
|
||||
else
|
||||
@ -178,7 +179,9 @@ class Pathname
|
||||
T.unsafe(self).open("a", **open_args) { |f| f.puts(content) }
|
||||
end
|
||||
|
||||
# @note This always overwrites.
|
||||
# Write to a file atomically.
|
||||
#
|
||||
# NOTE: This always overwrites.
|
||||
#
|
||||
# @api public
|
||||
sig { params(content: String).void }
|
||||
@ -201,6 +204,7 @@ class Pathname
|
||||
# Changing file ownership failed, moving on.
|
||||
nil
|
||||
end
|
||||
|
||||
begin
|
||||
# This operation will affect filesystem ACL's
|
||||
chmod(old_stat.mode)
|
||||
|
||||
@ -20,7 +20,7 @@ module Homebrew
|
||||
if os.present?
|
||||
return true
|
||||
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
|
||||
end
|
||||
return true if arch.present?
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -16,7 +16,8 @@ module Homebrew
|
||||
@assertions ||= 0
|
||||
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
|
||||
def shell_output(cmd, result = 0)
|
||||
ohai cmd
|
||||
@ -28,8 +29,9 @@ module Homebrew
|
||||
raise
|
||||
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.
|
||||
#
|
||||
# @api public
|
||||
def pipe_output(cmd, input = nil, result = nil)
|
||||
ohai cmd
|
||||
|
||||
@ -99,6 +99,8 @@ module Homebrew
|
||||
|
||||
sig { returns(String) }
|
||||
def template
|
||||
# FIXME: https://github.com/errata-ai/vale/issues/818
|
||||
# <!-- vale off -->
|
||||
<<~ERB
|
||||
# Documentation: https://docs.brew.sh/Formula-Cookbook
|
||||
# https://rubydoc.brew.sh/Formula
|
||||
@ -183,14 +185,14 @@ module Homebrew
|
||||
ENV.prepend_create_path "PERL5LIB", libexec/"lib/perl5"
|
||||
ENV.prepend_path "PERL5LIB", libexec/"lib"
|
||||
|
||||
# Stage additional dependency (Makefile.PL style)
|
||||
# Stage additional dependency (`Makefile.PL` style).
|
||||
# resource("").stage do
|
||||
# system "perl", "Makefile.PL", "INSTALL_BASE=\#{libexec}"
|
||||
# system "make"
|
||||
# system "make", "install"
|
||||
# end
|
||||
|
||||
# Stage additional dependency (Build.PL style)
|
||||
# Stage additional dependency (`Build.PL` style).
|
||||
# resource("").stage do
|
||||
# system "perl", "Build.PL", "--install_base", libexec
|
||||
# system "./Build"
|
||||
@ -231,6 +233,7 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
ERB
|
||||
# <!-- vale on -->
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -37,7 +37,6 @@ class KegOnlyReason
|
||||
!by_macos?
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
return @explanation unless @explanation.empty?
|
||||
|
||||
@ -25,7 +25,6 @@ module Homebrew
|
||||
@text.include? string
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
@text
|
||||
|
||||
@ -537,19 +537,19 @@ module Formulary
|
||||
class FormulaLoader
|
||||
include Context
|
||||
|
||||
# The formula's name
|
||||
# The formula's name.
|
||||
sig { returns(String) }
|
||||
attr_reader :name
|
||||
|
||||
# The formula's ruby file's path or filename
|
||||
# The formula file's path.
|
||||
sig { returns(Pathname) }
|
||||
attr_reader :path
|
||||
|
||||
# The name used to install the formula
|
||||
# The name used to install the formula.
|
||||
sig { returns(T.nilable(Pathname)) }
|
||||
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)) }
|
||||
attr_reader :tap
|
||||
|
||||
@ -1019,8 +1019,8 @@ module Formulary
|
||||
# Return a {Formula} instance for the given rack.
|
||||
#
|
||||
# @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
|
||||
# installed, and discarded if it is installed because the `alias_path` used
|
||||
# @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
|
||||
# to install the formula will be set instead.
|
||||
sig {
|
||||
params(
|
||||
|
||||
@ -106,7 +106,6 @@ class GitRepository
|
||||
popen_git("log", "-1", "--pretty=%B", commit, "--", safe:, err: :out)&.strip
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s = pathname.to_s
|
||||
|
||||
|
||||
@ -94,12 +94,12 @@ class GitHubPackages
|
||||
end
|
||||
|
||||
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-")
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
"#{prefix}#{org}/#{repo_without_prefix(repo)}"
|
||||
@ -115,9 +115,9 @@ class GitHubPackages
|
||||
end
|
||||
|
||||
def self.image_formula_name(formula_name)
|
||||
# invalid docker name characters
|
||||
# / makes sense because we already use it to separate repo/formula
|
||||
# x makes sense because we already use it in Formulary
|
||||
# Invalid docker name characters:
|
||||
# - `/` makes sense because we already use it to separate repository/formula.
|
||||
# - `x` makes sense because we already use it in `Formulary`.
|
||||
formula_name.tr("@", "/")
|
||||
.tr("+", "x")
|
||||
end
|
||||
@ -231,9 +231,9 @@ class GitHubPackages
|
||||
inspect_args << "--creds=#{user}:#{token}"
|
||||
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/)
|
||||
# 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
|
||||
opoo "#{image_uri} inspection returned an error, skipping upload!\n#{inspect_result.stderr}"
|
||||
return
|
||||
@ -241,11 +241,11 @@ class GitHubPackages
|
||||
odie "#{image_uri} inspection returned an error!\n#{inspect_result.stderr}"
|
||||
end
|
||||
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?
|
||||
# Otherwise, do nothing - the tag already existing is expected behaviour for --keep-old.
|
||||
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
|
||||
opoo "#{image_uri} already exists, skipping upload!"
|
||||
return
|
||||
|
||||
@ -48,7 +48,6 @@ class Keg
|
||||
EOS
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
s = []
|
||||
@ -67,7 +66,6 @@ class Keg
|
||||
|
||||
# Error for when a directory is not writable.
|
||||
class DirectoryNotWritableError < LinkError
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
<<~EOS
|
||||
@ -176,11 +174,9 @@ class Keg
|
||||
path.parent
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s = path.to_s
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def inspect
|
||||
"#<#{self.class.name}:#{path}>"
|
||||
@ -556,8 +552,8 @@ class Keg
|
||||
|
||||
src = dst.resolved_path
|
||||
|
||||
# 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
|
||||
# `src` itself may be a symlink, so check lstat to ensure we are dealing with
|
||||
# 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.
|
||||
|
||||
begin
|
||||
|
||||
@ -14,7 +14,7 @@ module Language
|
||||
# e.g. `resource "github.com/foo/bar"`.
|
||||
sig { params(resources: T::Array[Resource], target: T.any(String, Pathname)).void }
|
||||
def self.stage_deps(resources, target)
|
||||
# odeprecated "Language::Go::stage_deps", "Go modules"
|
||||
# odeprecated "`Language::Go.stage_deps`", "Go modules"
|
||||
if resources.empty?
|
||||
if Homebrew::EnvConfig.developer?
|
||||
odie "Tried to stage empty Language::Go resources array"
|
||||
|
||||
@ -144,14 +144,14 @@ module Language
|
||||
|
||||
# Mixin module for {Formula} adding virtualenv support features.
|
||||
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
|
||||
# installing packages into a Python virtualenv.
|
||||
#
|
||||
# @param venv_root [Pathname, String] the path to the root of the virtualenv
|
||||
# (often `libexec/"venv"`)
|
||||
# @param python [String, Pathname] which interpreter to use (e.g. "python3"
|
||||
# or "python3.x")
|
||||
# @param python [String, Pathname] which interpreter to use (e.g. `"python3"`
|
||||
# or `"python3.x"`)
|
||||
# @param formula [Formula] the active {Formula}
|
||||
# @return [Virtualenv] a {Virtualenv} instance
|
||||
sig {
|
||||
@ -166,7 +166,7 @@ module Language
|
||||
def virtualenv_create(venv_root, python = "python", formula = T.cast(self, Formula),
|
||||
system_site_packages: true, without_pip: true)
|
||||
# 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
|
||||
python_version = Language::Python.major_minor_version(python)
|
||||
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
|
||||
# active or if the specified python is required by the formula. Valid
|
||||
# inputs are "python", "python2", and :python3. Note that
|
||||
# "with-python", "without-python", "with-python@2", and "without-python@2"
|
||||
# inputs are `"python"`, `"python2"` and `:python3`. Note that
|
||||
# `"with-python"`, `"without-python"`, `"with-python@2"` and `"without-python@2"`
|
||||
# formula options are handled correctly even if not associated with any
|
||||
# corresponding depends_on statement.
|
||||
sig { params(python: String).returns(T::Boolean) }
|
||||
@ -211,7 +211,7 @@ module Language
|
||||
|
||||
# Helper method for the common case of installing a Python application.
|
||||
# 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
|
||||
# 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
|
||||
|
||||
@ -16,15 +16,20 @@ class LazyObject < Delegator
|
||||
@__delegate__ = @__callable__.call
|
||||
# rubocop:enable Naming/MemoizedInstanceVariableName
|
||||
end
|
||||
private :__getobj__
|
||||
|
||||
def __setobj__(callable)
|
||||
@__callable__ = callable
|
||||
end
|
||||
private :__setobj__
|
||||
|
||||
# Forward to the inner object to make lazy objects type-checkable.
|
||||
#
|
||||
# @!visibility private
|
||||
def is_a?(klass)
|
||||
# see https://sorbet.org/docs/faq#how-can-i-fix-type-errors-that-arise-from-super
|
||||
T.bind(self, T.untyped)
|
||||
|
||||
__getobj__.is_a?(klass) || super
|
||||
end
|
||||
end
|
||||
|
||||
@ -39,9 +39,11 @@ module Homebrew
|
||||
) do
|
||||
extend Forwardable
|
||||
|
||||
# @!attribute [r] version
|
||||
# @api public
|
||||
delegate version: :bundle_version
|
||||
|
||||
# @!attribute [r] short_version
|
||||
# @api public
|
||||
delegate short_version: :bundle_version
|
||||
end
|
||||
|
||||
@ -13,7 +13,7 @@ module Homebrew
|
||||
# Livecheck has historically prioritized the {Git} strategy over others
|
||||
# and this behavior was continued when the priority setup was created.
|
||||
# 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
|
||||
# behavior.
|
||||
#
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
module Homebrew
|
||||
module Livecheck
|
||||
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
|
||||
# in the `livecheck` block, it should be passed as the second argument to
|
||||
# the `strategy` block.
|
||||
|
||||
@ -54,12 +54,15 @@ module Homebrew
|
||||
) do
|
||||
extend Forwardable
|
||||
|
||||
# @!attribute [r] version
|
||||
# @api public
|
||||
delegate version: :bundle_version
|
||||
|
||||
# @!attribute [r] short_version
|
||||
# @api public
|
||||
delegate short_version: :bundle_version
|
||||
|
||||
# @!attribute [r] nice_version
|
||||
# @api public
|
||||
delegate nice_version: :bundle_version
|
||||
end
|
||||
|
||||
@ -5,7 +5,7 @@ module Homebrew
|
||||
module Livecheck
|
||||
module Strategy
|
||||
# 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
|
||||
# as the second argument to the `strategy` block.
|
||||
#
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
module Homebrew
|
||||
module Livecheck
|
||||
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
|
||||
# in the `livecheck` block, it should be passed as the second argument to
|
||||
# the `strategy` block.
|
||||
|
||||
@ -106,7 +106,6 @@ class Locale
|
||||
locale_groups.find { |locales| locales.any? { |locale| include?(locale) } }
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
[@language, @script, @region].compact.join("-")
|
||||
|
||||
@ -132,6 +132,7 @@ class MacOSVersion < Version
|
||||
alias requires_popcnt? requires_nehalem_cpu?
|
||||
|
||||
# Represents the absence of a version.
|
||||
#
|
||||
# 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
|
||||
end
|
||||
@ -141,7 +142,7 @@ require "lazy_object"
|
||||
module MacOSVersionErrorCompat
|
||||
def const_missing(name)
|
||||
if name == :MacOSVersionError
|
||||
odisabled "MacOSVersionError", "MacOSVersion::Error"
|
||||
odisabled "`MacOSVersionError`", "`MacOSVersion::Error`"
|
||||
return MacOSVersion::Error
|
||||
end
|
||||
|
||||
@ -158,7 +159,7 @@ end
|
||||
|
||||
module MacOSVersions
|
||||
SYMBOLS = LazyObject.new do # rubocop:disable Style/MutableConstant
|
||||
odisabled "MacOSVersions::SYMBOLS", "MacOSVersion::SYMBOLS"
|
||||
odisabled "`MacOSVersions::SYMBOLS`", "`MacOSVersion::SYMBOLS`"
|
||||
MacOSVersion::SYMBOLS
|
||||
end
|
||||
end
|
||||
@ -167,7 +168,7 @@ module OS
|
||||
module Mac
|
||||
# TODO: Replace `::Version` with `Version` when this is removed.
|
||||
Version = LazyObject.new do # rubocop:disable Style/MutableConstant
|
||||
odisabled "OS::Mac::Version", "MacOSVersion"
|
||||
odisabled "`OS::Mac::Version`", "`MacOSVersion`"
|
||||
MacOSVersion
|
||||
end
|
||||
end
|
||||
|
||||
@ -142,7 +142,7 @@ module Homebrew
|
||||
|
||||
sig { returns(String) }
|
||||
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"]
|
||||
lines += Homebrew::CLI::Parser.global_cask_options.map do |_, long, kwargs|
|
||||
generate_option_doc(nil, long.chomp("="), kwargs.fetch(:description))
|
||||
|
||||
@ -287,17 +287,18 @@ class Migrator
|
||||
def repin
|
||||
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
|
||||
# <dir>/../<...>/../Cellar/name/version.
|
||||
# To repin formula we need to update the link thus that it points to
|
||||
# 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
|
||||
# Pathname#make_relative_symlink, where Pathname#relative_path_from
|
||||
# is used to find relative path from source to destination parent and
|
||||
# it assumes no symlinks.
|
||||
# `Pathname#make_relative_symlink`, where `Pathname#relative_path_from`
|
||||
# is used to find the relative path from source to destination parent
|
||||
# and it assumes no symlinks.
|
||||
src_oldname = (old_pin_record.dirname/old_pin_link_record).expand_path
|
||||
new_pin_record.make_relative_symlink(src_oldname.sub(oldname, newname))
|
||||
old_pin_record.delete
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
# typed: 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.
|
||||
class Mktemp
|
||||
include FileUtils
|
||||
@ -38,7 +38,6 @@ class Mktemp
|
||||
@quiet = true
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
"[Mktemp: #{tmpdir} retain=#{@retain} quiet=#{@quiet}]"
|
||||
|
||||
@ -11,7 +11,6 @@ class Option
|
||||
@description = description
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s = flag
|
||||
|
||||
@ -30,7 +29,6 @@ class Option
|
||||
name.hash
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def inspect
|
||||
"#<#{self.class.name}: #{flag.inspect}>"
|
||||
@ -134,13 +132,11 @@ class Options
|
||||
|
||||
alias to_ary to_a
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
@options.map(&:to_s).join(" ")
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def inspect
|
||||
"#<#{self.class.name}: #{to_a.inspect}>"
|
||||
|
||||
@ -173,8 +173,8 @@ module OS
|
||||
# using that.
|
||||
# As of Xcode 10, the Unix-style headers are installed via a
|
||||
# separate package, so we can't rely on their being present.
|
||||
# This will only look up SDKs on Xcode 10 or newer, and still
|
||||
# return nil SDKs for Xcode 9 and older.
|
||||
# This will only look up SDKs on Xcode 10 or newer and still
|
||||
# return `nil` SDKs for Xcode 9 and older.
|
||||
sig { override.returns(String) }
|
||||
def sdk_prefix
|
||||
@sdk_prefix ||= if CLT.provides_sdk?
|
||||
|
||||
@ -51,7 +51,6 @@ class EmbeddedPatch
|
||||
Utils.safe_popen_write("patch", *args) { |p| p.write(data) }
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def inspect
|
||||
"#<#{self.class.name}: #{strip.inspect}>"
|
||||
@ -151,7 +150,6 @@ class ExternalPatch
|
||||
raise BuildError.new(f, cmd, args, ENV.to_hash)
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def inspect
|
||||
"#<#{self.class.name}: #{strip.inspect} #{url.inspect}>"
|
||||
|
||||
@ -39,7 +39,6 @@ class PkgVersion
|
||||
end
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s = to_str
|
||||
|
||||
|
||||
@ -140,7 +140,6 @@ class Requirement
|
||||
[self.class, name, tags].hash
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def inspect
|
||||
"#<#{self.class.name}: #{tags.inspect}>"
|
||||
|
||||
@ -27,7 +27,6 @@ class ArchRequirement < Requirement
|
||||
"The #{@arch} architecture is required for this software."
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def inspect
|
||||
"#<#{self.class.name}: arch=#{@arch.to_s.inspect} #{tags.inspect}>"
|
||||
|
||||
@ -96,7 +96,6 @@ class MacOSRequirement < Requirement
|
||||
[super, comparator, version].hash
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def inspect
|
||||
"#<#{self.class.name}: version#{@comparator}#{@version.to_s.inspect} #{tags.inspect}>"
|
||||
|
||||
@ -48,7 +48,6 @@ class XcodeRequirement < Requirement
|
||||
end
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def inspect
|
||||
"#<#{self.class.name}: version>=#{@version.inspect} #{tags.inspect}>"
|
||||
|
||||
@ -146,17 +146,22 @@ class Resource < Downloadable
|
||||
super(verify_download_integrity:)
|
||||
end
|
||||
|
||||
# @!attribute [w] livecheck
|
||||
# {Livecheck} can be used to check for newer versions of the software.
|
||||
# This method evaluates the DSL specified in the livecheck block of the
|
||||
# {Resource} (if it exists) and sets the instance variables of a {Livecheck}
|
||||
# object accordingly. This is used by `brew livecheck` to check for newer
|
||||
# versions of the software.
|
||||
#
|
||||
# <pre>livecheck do
|
||||
# ### Example
|
||||
#
|
||||
# ```ruby
|
||||
# livecheck do
|
||||
# url "https://example.com/foo/releases"
|
||||
# regex /foo-(\d+(?:\.\d+)+)\.tar/
|
||||
# end</pre>
|
||||
# end
|
||||
# ```
|
||||
#
|
||||
# @!attribute [w] livecheck
|
||||
def livecheck(&block)
|
||||
return @livecheck unless block
|
||||
|
||||
@ -165,8 +170,8 @@ class Resource < Downloadable
|
||||
end
|
||||
|
||||
# Whether a livecheck specification is defined or not.
|
||||
# It returns true when a livecheck block is present in the {Resource} and
|
||||
# false otherwise, and is used by livecheck.
|
||||
# It returns true when a `livecheck` block is present in the {Resource} and
|
||||
# false otherwise and is used by livecheck.
|
||||
def livecheckable?
|
||||
@livecheckable == true
|
||||
end
|
||||
@ -302,7 +307,6 @@ class ResourceStageContext
|
||||
@staging = staging
|
||||
end
|
||||
|
||||
# @!visibility private
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
"<#{self.class}: resource=#{resource} staging=#{staging}>"
|
||||
|
||||
@ -4,27 +4,26 @@
|
||||
module RuboCop
|
||||
module Cop
|
||||
module Homebrew
|
||||
# Checks for code that can be written with simpler conditionals
|
||||
# using `Object#blank?`.
|
||||
# Checks for code that can be simplified using `Object#blank?`.
|
||||
#
|
||||
# @note
|
||||
# This cop is unsafe autocorrection, because `' '.empty?` returns false,
|
||||
# but `' '.blank?` returns true. Therefore, autocorrection is not compatible
|
||||
# if the receiver is a non-empty blank string, tab, or newline meta characters.
|
||||
# NOTE: Auto-correction for this cop is unsafe because `' '.empty?` returns `false`,
|
||||
# but `' '.blank?` returns `true`. Therefore, auto-correction is not compatible
|
||||
# if the receiver is a non-empty blank string.
|
||||
#
|
||||
# @example
|
||||
# # Converts usages of `nil? || empty?` to `blank?`
|
||||
# ### Example
|
||||
#
|
||||
# # bad
|
||||
# foo.nil? || foo.empty?
|
||||
# foo == nil || foo.empty?
|
||||
# ```ruby
|
||||
# # bad
|
||||
# foo.nil? || foo.empty?
|
||||
# foo == nil || foo.empty?
|
||||
#
|
||||
# # good
|
||||
# foo.blank?
|
||||
# # good
|
||||
# foo.blank?
|
||||
# ```
|
||||
class Blank < Base
|
||||
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
|
||||
# that have a single method call on the left hand side
|
||||
@ -49,7 +48,7 @@ module RuboCop
|
||||
nil_or_empty?(node) do |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|
|
||||
autocorrect(corrector, node)
|
||||
end
|
||||
|
||||
@ -44,7 +44,7 @@ module RuboCop
|
||||
end
|
||||
|
||||
# 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?("]") }
|
||||
|
||||
# Sort the lines that should be sorted
|
||||
|
||||
@ -9,20 +9,23 @@ module RuboCop
|
||||
module Cask
|
||||
# This cop makes sure that OS conditionals are consistent.
|
||||
#
|
||||
# @example
|
||||
# # bad
|
||||
# cask 'foo' do
|
||||
# if MacOS.version == :high_sierra
|
||||
# sha256 "..."
|
||||
# end
|
||||
# end
|
||||
# ### Example
|
||||
#
|
||||
# # good
|
||||
# cask 'foo' do
|
||||
# on_high_sierra do
|
||||
# sha256 "..."
|
||||
# end
|
||||
# ```ruby
|
||||
# # bad
|
||||
# cask 'foo' do
|
||||
# if MacOS.version == :high_sierra
|
||||
# sha256 "..."
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# # good
|
||||
# cask 'foo' do
|
||||
# on_high_sierra do
|
||||
# sha256 "..."
|
||||
# end
|
||||
# end
|
||||
# ```
|
||||
class OnSystemConditionals < Base
|
||||
extend Forwardable
|
||||
extend AutoCorrector
|
||||
|
||||
@ -6,16 +6,17 @@ module RuboCop
|
||||
module Cask
|
||||
# This cop checks that a cask's `url` stanza is formatted correctly.
|
||||
#
|
||||
# @example
|
||||
# # bad
|
||||
# url "https://example.com/download/foo.dmg",
|
||||
# verified: "https://example.com/download"
|
||||
# ### Example
|
||||
#
|
||||
# ```ruby
|
||||
# # bad
|
||||
# url "https://example.com/download/foo.dmg",
|
||||
# verified: "https://example.com/download"
|
||||
#
|
||||
# # good
|
||||
# url "https://example.com/download/foo.dmg",
|
||||
# verified: "example.com/download/"
|
||||
#
|
||||
# # good
|
||||
# url "https://example.com/download/foo.dmg",
|
||||
# verified: "example.com/download/"
|
||||
# ```
|
||||
class Url < Base
|
||||
extend AutoCorrector
|
||||
extend Forwardable
|
||||
@ -43,7 +44,7 @@ module RuboCop
|
||||
|
||||
# Skip if the URL and the verified value are the same.
|
||||
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
|
||||
# Skip if the verified value ends with a slash.
|
||||
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