Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 77 additions & 11 deletions Library/Homebrew/dev-cmd/bump-cask-pr.rb
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,11 @@ def replace_version_and_checksum(cask, new_hash, new_version, contents)
cask_sourcefile_path = cask.sourcefile_path
raise "unexpected nil cask.sourcefile_path" unless cask_sourcefile_path

old_cask = Cask::CaskLoader.load(cask_sourcefile_path)
contents = split_root_version_and_checksum(new_version, contents)

old_cask = Homebrew::SimulateSystem.with(os: default_cask_os, arch: :arm) do
Cask::CaskLoader.load(cask_sourcefile_path)
end
generate_system_options(cask, new_version).each do |os, arch|
tag = Utils::Bottles::Tag.new(system: os, arch:)
old_cask.refresh_for_tag(tag) do
Expand All @@ -307,25 +311,34 @@ def replace_version_and_checksum(cask, new_hash, new_version, contents)
bump_version = new_version.send(arch) || new_version.general
next unless bump_version

version_scope = cask_stanza_scope(contents, :version, arch)
contents = replace_cask_stanza_value(
contents, :version,
old_version.latest? ? :latest : old_version.to_s,
bump_version.latest? ? :latest : bump_version.to_s
bump_version.latest? ? :latest : bump_version.to_s,
within: version_scope
)

tmp_cask = Cask::CaskLoader::FromContentLoader.new(contents)
.load(config: nil)
old_hash = tmp_cask.sha256
next if new_hash.is_a?(String) && old_hash.to_s == new_hash
Comment on lines 322 to +325

checksum_scope = cask_stanza_scope(contents, :sha256, arch)
if tmp_cask.version.latest? || new_hash == :no_check
opoo "Ignoring specified `--sha256=` argument." if new_hash.is_a?(String)
if old_hash != :no_check
contents = replace_cask_stanza_value(contents, :sha256, old_hash.to_s,
:no_check)
contents = replace_cask_stanza_value(contents, :sha256, old_hash.to_s, :no_check,
within: checksum_scope)
end
elsif old_hash == :no_check && new_hash != :no_check
contents = replace_cask_stanza_value(contents, :sha256, :no_check, new_hash) if new_hash.is_a?(String)
elsif new_hash && !cask.on_system_blocks_exist? && cask.languages.empty?
contents = replace_cask_stanza_value(contents, :sha256, old_hash.to_s, new_hash.to_s)
if new_hash.is_a?(String) && (!arch_specific_version_bump?(new_version) || checksum_scope)
contents = replace_cask_stanza_value(contents, :sha256, :no_check, new_hash, within: checksum_scope)
end
elsif new_hash && cask.languages.empty? &&
(!cask.on_system_blocks_exist? || checksum_scope || arch_specific_version_bump?(new_version))
contents = replace_cask_stanza_value(contents, :sha256, old_hash.to_s, new_hash.to_s,
within: checksum_scope)
elsif old_hash != :no_check
opoo "Multiple checksum replacements required; ignoring specified `--sha256` argument." if new_hash
languages = if cask.languages.empty?
Expand All @@ -346,7 +359,8 @@ def replace_version_and_checksum(cask, new_hash, new_version, contents)
Utils::Tar.validate_file(download)

if new_cask.sha256.to_s != download.sha256
contents = replace_cask_stanza_value(contents, :sha256, new_cask.sha256.to_s, download.sha256)
contents = replace_cask_stanza_value(contents, :sha256, new_cask.sha256.to_s, download.sha256,
within: checksum_scope)
end
end
end
Expand All @@ -355,24 +369,76 @@ def replace_version_and_checksum(cask, new_hash, new_version, contents)
contents
end

sig {
params(
new_version: BumpVersionParser,
contents: String,
).returns(String)
}
def split_root_version_and_checksum(new_version, contents)
return contents unless arch_specific_version_bump?(new_version)

cask_ast = Utils::AST::CaskAST.new(contents)
root_version = cask_ast.first_stanza_value(:version, within: :root)
if root_version &&
!cask_ast.stanza_anywhere?(:version, within: :on_arm) &&
!cask_ast.stanza_anywhere?(:version, within: :on_intel)
cask_ast.replace_root_stanza_with_arch_blocks(:version, root_version)
contents = cask_ast.process
end

cask_ast = Utils::AST::CaskAST.new(contents)
root_sha256 = cask_ast.first_stanza_value(:sha256, within: :root)
if root_sha256.is_a?(String) &&
!cask_ast.stanza_anywhere?(:sha256, within: :on_arm) &&
!cask_ast.stanza_anywhere?(:sha256, within: :on_intel)
cask_ast.replace_root_stanza_with_arch_blocks(:sha256, root_sha256)
contents = cask_ast.process
end

contents
end

sig { params(new_version: BumpVersionParser).returns(T::Boolean) }
def arch_specific_version_bump?(new_version)
new_version.arm.present? || new_version.intel.present?
end

sig { returns(Symbol) }
def default_cask_os
current_os = Homebrew::SimulateSystem.current_os
return current_os if MacOSVersion::SYMBOLS.include?(current_os)

MacOSVersion.new(HOMEBREW_MACOS_NEWEST_SUPPORTED).to_sym
end

sig { params(contents: String, name: Symbol, arch: Symbol).returns(T.nilable(Symbol)) }
def cask_stanza_scope(contents, name, arch)
scope = :"on_#{arch}"
return scope if Utils::AST::CaskAST.new(contents).stanza?(name, within: scope)

nil
end

sig {
params(
contents: String,
name: Symbol,
old_value: T.any(Numeric, String, Symbol),
new_value: T.any(Numeric, String, Symbol),
within: T.nilable(Symbol),
).returns(String)
}
def replace_cask_stanza_value(contents, name, old_value, new_value)
def replace_cask_stanza_value(contents, name, old_value, new_value, within: nil)
return contents if old_value == new_value

cask_ast = Utils::AST::CaskAST.new(contents)
replacement_count = cask_ast.replace_stanza_value(name, old_value, new_value)
replacement_count = cask_ast.replace_stanza_value(name, old_value, new_value, within:)
if replacement_count.zero?
# Treat an already-applied replacement as a successful no-op so the
# per-(os, arch) loop in `replace_version_and_checksum` can yield the
# same general version more than once without raising.
return contents if cask_ast.replace_stanza_value(name, new_value, new_value).positive?
return contents if cask_ast.replace_stanza_value(name, new_value, new_value, within:).positive?

raise "Could not find '#{name}' stanza with value #{old_value.inspect}!"
end
Expand Down
65 changes: 44 additions & 21 deletions Library/Homebrew/dev-cmd/bump.rb
Original file line number Diff line number Diff line change
Expand Up @@ -702,27 +702,7 @@ def retrieve_and_display_info_and_open_pr(formula_or_cask, name, repositories, a

return if duplicate_pull_requests.present?

version_args = []
if multiple_versions[:current] && multiple_versions[:new]
if (new_version_arm = new_version.arm) &&
!message?(new_version_arm) &&
current_version.arm &&
new_version_arm > current_version.arm
version_args << "--version-arm=#{new_version_arm}"
end
if (new_version_intel = new_version.intel) &&
!message?(new_version_intel) &&
current_version.intel &&
new_version_intel > current_version.intel
version_args << "--version-intel=#{new_version_intel}"
end
elsif multiple_versions[:current]
opoo "`#{name}` needs to be manually updated using one version"
elsif multiple_versions[:new]
opoo "`#{name}` needs to be manually updated using arch-specific versions"
elsif new_version.general
version_args << "--version=#{new_version.general}"
end
version_args = version_args_for_bump(current_version:, new_version:, multiple_versions:, name:)
return if version_args.blank?

bump_pr_args = [
Expand Down Expand Up @@ -753,6 +733,49 @@ def retrieve_and_display_info_and_open_pr(formula_or_cask, name, repositories, a
Homebrew.failed = true unless result
end

sig {
params(
current_version: BumpVersionParser,
new_version: BumpVersionParser,
multiple_versions: T::Hash[Symbol, T::Boolean],
name: String,
).returns(T::Array[String])
}
def version_args_for_bump(current_version:, new_version:, multiple_versions:, name:)
version_args = T.let([], T::Array[String])

if multiple_versions[:new]
(BumpVersionParser::VERSION_SYMBOLS - [:general]).each do |arch|
new_arch_version = new_version.send(arch)
next if new_arch_version.blank? || message?(new_arch_version)

current_arch_version = if multiple_versions[:current]
current_version.send(arch)
else
current_version.general
end
next if current_arch_version.blank? || new_arch_version <= current_arch_version

version_args << "--version-#{arch}=#{new_arch_version}"
end
elsif multiple_versions[:current]
if (new_general_version = new_version.general) && !message?(new_general_version)
(BumpVersionParser::VERSION_SYMBOLS - [:general]).each do |arch|
current_arch_version = current_version.send(arch)
next if current_arch_version.blank? || new_general_version <= current_arch_version

version_args << "--version-#{arch}=#{new_general_version}"
end
end

opoo "`#{name}` needs to be manually updated using one version" if version_args.blank?
elsif new_version.general
version_args << "--version=#{new_version.general}"
end

version_args
end

sig {
params(
current_version: BumpVersionParser,
Expand Down
Loading
Loading