From 540a5b9d30db995bde8cfa0c19986693bfd5346c Mon Sep 17 00:00:00 2001 From: Razvan Azamfirei Date: Fri, 31 Mar 2023 18:01:34 -0400 Subject: [PATCH 01/28] temp --- Library/Homebrew/dev-cmd/bump-cask-pr.rb | 2 +- Library/Homebrew/env_config.rb | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/dev-cmd/bump-cask-pr.rb b/Library/Homebrew/dev-cmd/bump-cask-pr.rb index fe6303d764..be951dadbd 100644 --- a/Library/Homebrew/dev-cmd/bump-cask-pr.rb +++ b/Library/Homebrew/dev-cmd/bump-cask-pr.rb @@ -84,7 +84,7 @@ module Homebrew Cask::DSL::Version.new(new_version) end - new_hash = unless (new_hash = args.sha265).nil? + new_hash = unless (new_hash = args.sha256).nil? raise UsageError, "`--sha256` must not be empty." if new_hash.blank? ["no_check", ":no_check"].include?(new_hash) ? :no_check : new_hash diff --git a/Library/Homebrew/env_config.rb b/Library/Homebrew/env_config.rb index 3d0d0db091..54799a77d5 100644 --- a/Library/Homebrew/env_config.rb +++ b/Library/Homebrew/env_config.rb @@ -239,6 +239,9 @@ module Homebrew HOMEBREW_GITHUB_PACKAGES_USER: { description: "Use this username when accessing the GitHub Packages Registry (where bottles may be stored).", }, + HOMEBREW_GREEDY: { + description: "Pass this value to brew upgrade greedy.", + }, HOMEBREW_INSTALL_BADGE: { description: "Print this text before the installation summary of each successful build.", default_text: 'The "Beer Mug" emoji.', From a4e8f9e22b78c740cb0df0d3d8e70ff6c0bd6036 Mon Sep 17 00:00:00 2001 From: Issy Long Date: Wed, 29 Mar 2023 00:40:46 +0100 Subject: [PATCH 02/28] audit: Make `--display-failures-only` the default for Casks - Cask warnings are really noisy and numerous. Let's only show them if the user passes `--strict` or something implying `--strict`, like `--new-cask`. - Additionally remove `display_passes` since we would like silence if nothing is wrong with the cask, the same as with formula audits. --- Library/Homebrew/cask/audit.rb | 8 ++---- Library/Homebrew/cask/auditor.rb | 19 ++----------- Library/Homebrew/cask/cmd/audit.rb | 29 +++++++------------ Library/Homebrew/dev-cmd/audit.rb | 30 +++++++++++--------- Library/Homebrew/test/cask/cmd/audit_spec.rb | 10 ------- 5 files changed, 33 insertions(+), 63 deletions(-) diff --git a/Library/Homebrew/cask/audit.rb b/Library/Homebrew/cask/audit.rb index 8b65aca250..c9d299e3e9 100644 --- a/Library/Homebrew/cask/audit.rb +++ b/Library/Homebrew/cask/audit.rb @@ -109,14 +109,12 @@ module Cask Formatter.error("failed") elsif warnings? Formatter.warning("warning") - else - Formatter.success("passed") end end - sig { params(include_passed: T::Boolean, include_warnings: T::Boolean).returns(T.nilable(String)) } - def summary(include_passed: false, include_warnings: true) - return if success? && !include_passed + sig { params(include_warnings: T::Boolean).returns(T.nilable(String)) } + def summary(include_warnings: true) + return if success? return if warnings? && !errors? && !include_warnings summary = ["audit for #{cask}: #{result}"] diff --git a/Library/Homebrew/cask/auditor.rb b/Library/Homebrew/cask/auditor.rb index c4f93896dc..cae71e5d13 100644 --- a/Library/Homebrew/cask/auditor.rb +++ b/Library/Homebrew/cask/auditor.rb @@ -25,8 +25,6 @@ module Cask quarantine: nil, any_named_args: nil, language: nil, - display_passes: nil, - display_failures_only: nil, only: [], except: [] ) @@ -40,8 +38,6 @@ module Cask @audit_token_conflicts = audit_token_conflicts @any_named_args = any_named_args @language = language - @display_passes = display_passes - @display_failures_only = display_failures_only @only = only @except = except end @@ -63,7 +59,7 @@ module Cask sample_languages.each_key do |l| audit = audit_languages(l) - summary = audit.summary(include_passed: output_passed?, include_warnings: output_warnings?) + summary = audit.summary(include_warnings: output_warnings?) if summary.present? && output_summary?(audit) ohai "Auditing language: #{l.map { |lang| "'#{lang}'" }.to_sentence}" if output_summary? puts summary @@ -73,7 +69,7 @@ module Cask end else audit = audit_cask_instance(cask) - summary = audit.summary(include_passed: output_passed?, include_warnings: output_warnings?) + summary = audit.summary(include_warnings: output_warnings?) puts summary if summary.present? && output_summary?(audit) warnings += audit.warnings errors += audit.errors @@ -92,17 +88,8 @@ module Cask audit.errors? end - def output_passed? - return false if @display_failures_only.present? - return true if @display_passes.present? - - false - end - def output_warnings? - return false if @display_failures_only.present? - - true + @new_cask.present? || @audit_strict.present? end def audit_languages(languages) diff --git a/Library/Homebrew/cask/cmd/audit.rb b/Library/Homebrew/cask/cmd/audit.rb index 35179c3455..0c65d24b22 100644 --- a/Library/Homebrew/cask/cmd/audit.rb +++ b/Library/Homebrew/cask/cmd/audit.rb @@ -30,8 +30,6 @@ module Cask description: "Run various additional style checks to determine if a new cask is eligible " \ "for Homebrew. This should be used when creating new casks and implies " \ "`--strict` and `--online`" - switch "--display-failures-only", - description: "Only display casks that fail the audit. This is the default for formulae." end end @@ -49,19 +47,17 @@ module Cask results = self.class.audit_casks( *casks, - download: args.download?, - online: args.online?, - strict: args.strict?, - signing: args.signing?, - new_cask: args.new_cask?, - token_conflicts: args.token_conflicts?, - quarantine: args.quarantine?, - any_named_args: any_named_args, - language: args.language, - display_passes: args.verbose? || args.named.count == 1, - display_failures_only: args.display_failures_only?, - only: [], - except: [], + download: args.download?, + online: args.online?, + strict: args.strict?, + signing: args.signing?, + new_cask: args.new_cask?, + token_conflicts: args.token_conflicts?, + quarantine: args.quarantine?, + any_named_args: any_named_args, + language: args.language, + only: [], + except: [], ) failed_casks = results.reject { |_, result| result[:errors].empty? }.map(&:first) @@ -81,8 +77,6 @@ module Cask quarantine:, any_named_args:, language:, - display_passes:, - display_failures_only:, only:, except: ) @@ -96,7 +90,6 @@ module Cask quarantine: quarantine, language: language, any_named_args: any_named_args, - display_passes: display_passes, display_failures_only: display_failures_only, only: only, except: except, diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index a481432293..7cb204f9cb 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -65,7 +65,7 @@ module Homebrew description: "Prefix every line of output with the file or formula name being audited, to " \ "make output easy to grep." switch "--display-failures-only", - description: "Only display casks that fail the audit. This is the default for formulae." + description: "Only display casks that fail the audit. This is the default for formulae and casks." switch "--skip-style", description: "Skip running non-RuboCop style checks. Useful if you plan on running " \ "`brew style` separately. Enabled by default unless a formula is specified by name." @@ -242,24 +242,26 @@ module Homebrew require "cask/cmd/abstract_command" require "cask/cmd/audit" + if args.display_failures_only? + odeprecated "`brew audit --display-failures-only`", "`brew audit ` without the argument" + end + # For switches, we add `|| nil` so that `nil` will be passed instead of `false` if they aren't set. # This way, we can distinguish between "not set" and "set to false". Cask::Cmd::Audit.audit_casks( *audit_casks, - download: nil, + download: nil, # No need for `|| nil` for `--[no-]signing` because boolean switches are already `nil` if not passed - signing: args.signing?, - online: args.online? || nil, - strict: args.strict? || nil, - new_cask: args.new_cask? || nil, - token_conflicts: args.token_conflicts? || nil, - quarantine: nil, - any_named_args: !no_named_args, - language: nil, - display_passes: args.verbose? || args.named.count == 1, - display_failures_only: args.display_failures_only?, - only: args.only, - except: args.except, + signing: args.signing?, + online: args.online? || nil, + strict: args.strict? || nil, + new_cask: args.new_cask? || nil, + token_conflicts: args.token_conflicts? || nil, + quarantine: nil, + any_named_args: !no_named_args, + language: nil, + only: args.only, + except: args.except, ) end diff --git a/Library/Homebrew/test/cask/cmd/audit_spec.rb b/Library/Homebrew/test/cask/cmd/audit_spec.rb index cf15e3939a..12728b4777 100644 --- a/Library/Homebrew/test/cask/cmd/audit_spec.rb +++ b/Library/Homebrew/test/cask/cmd/audit_spec.rb @@ -25,7 +25,6 @@ describe Cask::Cmd::Audit, :cask do .with( cask, audit_new_cask: false, quarantine: true, any_named_args: true, - display_failures_only: false, display_passes: true, only: [], except: [] ) .and_return(result) @@ -40,7 +39,6 @@ describe Cask::Cmd::Audit, :cask do .with( cask, audit_new_cask: false, quarantine: true, any_named_args: true, - display_failures_only: false, display_passes: true, only: [], except: [] ) .and_return(result) @@ -54,7 +52,6 @@ describe Cask::Cmd::Audit, :cask do .with( cask, audit_download: true, audit_new_cask: false, quarantine: true, any_named_args: true, - display_failures_only: false, display_passes: true, only: [], except: [] ) .and_return(result) @@ -68,7 +65,6 @@ describe Cask::Cmd::Audit, :cask do .with( cask, audit_token_conflicts: true, audit_new_cask: false, quarantine: true, any_named_args: true, - display_failures_only: false, display_passes: true, only: [], except: [] ) .and_return(result) @@ -82,7 +78,6 @@ describe Cask::Cmd::Audit, :cask do .with( cask, audit_strict: true, audit_new_cask: false, quarantine: true, any_named_args: true, - display_failures_only: false, display_passes: true, only: [], except: [] ) .and_return(result) @@ -96,7 +91,6 @@ describe Cask::Cmd::Audit, :cask do .with( cask, audit_online: true, audit_new_cask: false, quarantine: true, any_named_args: true, - display_failures_only: false, display_passes: true, only: [], except: [] ) .and_return(result) @@ -110,7 +104,6 @@ describe Cask::Cmd::Audit, :cask do .with( cask, audit_new_cask: true, quarantine: true, any_named_args: true, - display_failures_only: false, display_passes: true, only: [], except: [] ) .and_return(result) @@ -124,7 +117,6 @@ describe Cask::Cmd::Audit, :cask do .with( cask, audit_new_cask: false, quarantine: true, language: ["de-AT"], any_named_args: true, - display_failures_only: false, display_passes: true, only: [], except: [] ) .and_return(result) @@ -138,7 +130,6 @@ describe Cask::Cmd::Audit, :cask do .with( cask, audit_new_cask: false, quarantine: false, any_named_args: true, - display_failures_only: false, display_passes: true, only: [], except: [] ) .and_return(result) @@ -154,7 +145,6 @@ describe Cask::Cmd::Audit, :cask do .with( cask, audit_new_cask: false, quarantine: false, any_named_args: true, - display_failures_only: false, display_passes: true, only: [], except: [] ) .and_return(result) From 2b8127d5181b4f8a7e56b1afc210ec454162829a Mon Sep 17 00:00:00 2001 From: Issy Long Date: Thu, 30 Mar 2023 23:52:24 +0100 Subject: [PATCH 03/28] Turn cask warnings into errors when `--strict` is passed (or implied) - Ignore them and don't show them otherwise. - Part three of issue 15074: > As a result, I propose that all current cask audit warnings are never > displayed as warnings but the underlying audit checks turned into > errors displayed only with --strict (or one of the other relevant > flags). --- Library/Homebrew/cask/audit.rb | 35 ++------ Library/Homebrew/cask/auditor.rb | 13 +-- Library/Homebrew/cask/cmd/audit.rb | 1 - Library/Homebrew/test/cask/audit_spec.rb | 81 ++++++++++++------- Library/Homebrew/test/cask/quarantine_spec.rb | 8 +- 5 files changed, 66 insertions(+), 72 deletions(-) diff --git a/Library/Homebrew/cask/audit.rb b/Library/Homebrew/cask/audit.rb index c9d299e3e9..aab2793c12 100644 --- a/Library/Homebrew/cask/audit.rb +++ b/Library/Homebrew/cask/audit.rb @@ -71,23 +71,14 @@ module Cask @errors ||= [] end - def warnings - @warnings ||= [] - end - sig { returns(T::Boolean) } def errors? errors.any? end - sig { returns(T::Boolean) } - def warnings? - warnings.any? - end - sig { returns(T::Boolean) } def success? - !(errors? || warnings?) + !errors? end sig { params(message: T.nilable(String), location: T.nilable(String)).void } @@ -97,25 +88,17 @@ module Cask sig { params(message: T.nilable(String), location: T.nilable(String)).void } def add_warning(message, location: nil) - if strict? - add_error message, location: location - else - warnings << ({ message: message, location: location }) - end + # Warnings are ignored unless `--strict` is passed in which case they're turned into errors. + add_error(message, location: location) if strict? end def result - if errors? - Formatter.error("failed") - elsif warnings? - Formatter.warning("warning") - end + Formatter.error("failed") if errors? end - sig { params(include_warnings: T::Boolean).returns(T.nilable(String)) } - def summary(include_warnings: true) + sig { returns(T.nilable(String)) } + def summary return if success? - return if warnings? && !errors? && !include_warnings summary = ["audit for #{cask}: #{result}"] @@ -123,12 +106,6 @@ module Cask summary << " #{Formatter.error("-")} #{error[:message]}" end - if include_warnings - warnings.each do |warning| - summary << " #{Formatter.warning("-")} #{warning[:message]}" - end - end - summary.join("\n") end diff --git a/Library/Homebrew/cask/auditor.rb b/Library/Homebrew/cask/auditor.rb index cae71e5d13..7a744f2172 100644 --- a/Library/Homebrew/cask/auditor.rb +++ b/Library/Homebrew/cask/auditor.rb @@ -45,7 +45,6 @@ module Cask LANGUAGE_BLOCK_LIMIT = 10 def audit - warnings = Set.new errors = Set.new if !language && language_blocks @@ -59,23 +58,19 @@ module Cask sample_languages.each_key do |l| audit = audit_languages(l) - summary = audit.summary(include_warnings: output_warnings?) - if summary.present? && output_summary?(audit) + if audit.summary.present? && output_summary?(audit) ohai "Auditing language: #{l.map { |lang| "'#{lang}'" }.to_sentence}" if output_summary? - puts summary + puts audit.summary end - warnings += audit.warnings errors += audit.errors end else audit = audit_cask_instance(cask) - summary = audit.summary(include_warnings: output_warnings?) - puts summary if summary.present? && output_summary?(audit) - warnings += audit.warnings + puts audit.summary if audit.summary.present? && output_summary?(audit) errors += audit.errors end - { warnings: warnings, errors: errors } + { errors: errors } end private diff --git a/Library/Homebrew/cask/cmd/audit.rb b/Library/Homebrew/cask/cmd/audit.rb index 0c65d24b22..59d759f8d2 100644 --- a/Library/Homebrew/cask/cmd/audit.rb +++ b/Library/Homebrew/cask/cmd/audit.rb @@ -90,7 +90,6 @@ module Cask quarantine: quarantine, language: language, any_named_args: any_named_args, - display_failures_only: display_failures_only, only: only, except: except, }.compact diff --git a/Library/Homebrew/test/cask/audit_spec.rb b/Library/Homebrew/test/cask/audit_spec.rb index 251aa00217..873fdb954a 100644 --- a/Library/Homebrew/test/cask/audit_spec.rb +++ b/Library/Homebrew/test/cask/audit_spec.rb @@ -13,23 +13,14 @@ describe Cask::Audit, :cask do end def passed?(audit) - !audit.errors? && !audit.warnings? + !audit.errors? end def outcome(audit) if passed?(audit) "passed" else - message = "" - - message += "warned with #{audit.warnings.map { |e| e.fetch(:message).inspect }.join(",")}" if audit.warnings? - - if audit.errors? - message += " and " if audit.warnings? - message += "errored with #{audit.errors.map { |e| e.fetch(:message).inspect }.join(",")}" - end - - message + "errored with #{audit.errors.map { |e| e.fetch(:message).inspect }.join(",")}" end end @@ -55,7 +46,7 @@ describe Cask::Audit, :cask do matcher :warn_with do |message| match do |audit| - include_msg?(audit.warnings, message) + include_msg?(audit.errors, message) end failure_message do |audit| @@ -118,6 +109,14 @@ describe Cask::Audit, :cask do describe "#result" do subject { audit.result } + context "when there are no errors and `--strict` is not passed so we should not show anything" do + before do + audit.add_warning "eh" + end + + it { is_expected.not_to match(/failed/) } + end + context "when there are errors" do before do audit.add_error "bad" @@ -126,14 +125,6 @@ describe Cask::Audit, :cask do it { is_expected.to match(/failed/) } end - context "when there are warnings" do - before do - audit.add_warning "eh" - end - - it { is_expected.to match(/warning/) } - end - context "when there are errors and warnings" do before do audit.add_error "bad" @@ -143,8 +134,33 @@ describe Cask::Audit, :cask do it { is_expected.to match(/failed/) } end - context "when there are no errors or warnings" do - it { is_expected.to match(/passed/) } + context "when there are errors and warnings and `--strict` is passed" do + let(:strict) { true } + + before do + audit.add_error "very bad" + audit.add_warning "a little bit bad" + end + + it { is_expected.to match(/failed/) } + end + + context "when there are warnings and `--strict` is not passed" do + before do + audit.add_warning "a little bit bad" + end + + it { is_expected.not_to match(/failed/) } + end + + context "when there are warnings and `--strict` is passed" do + let(:strict) { true } + + before do + audit.add_warning "a little bit bad" + end + + it { is_expected.to match(/failed/) } end end @@ -984,9 +1000,20 @@ describe Cask::Audit, :cask do context "when cask token conflicts with a core formula" do let(:formula_names) { %w[with-binary other-formula] } - it "warns about duplicates" do - expect(audit).to receive(:core_formula_names).and_return(formula_names) - expect(run).to warn_with(/possible duplicate/) + context "when `--strict` is passed" do + let(:strict) { true } + + it "warns about duplicates" do + expect(audit).to receive(:core_formula_names).and_return(formula_names) + expect(run).to warn_with(/possible duplicate/) + end + end + + context "when `--strict` is not passed" do + it "does not warn about duplicates" do + expect(audit).to receive(:core_formula_names).and_return(formula_names) + expect(run).not_to warn_with(/possible duplicate/) + end end end @@ -1058,8 +1085,8 @@ describe Cask::Audit, :cask do context "when `new_cask` is false" do let(:new_cask) { false } - it "warns" do - expect(run).to warn_with(/should have a description/) + it "does not warn" do + expect(run).not_to warn_with(/should have a description/) end end diff --git a/Library/Homebrew/test/cask/quarantine_spec.rb b/Library/Homebrew/test/cask/quarantine_spec.rb index f14d4bd70b..b5c49772da 100644 --- a/Library/Homebrew/test/cask/quarantine_spec.rb +++ b/Library/Homebrew/test/cask/quarantine_spec.rb @@ -39,9 +39,7 @@ describe Cask::Quarantine, :cask do it "quarantines Cask audits" do expect do Cask::Cmd::Audit.run("local-transmission", "--download") - end.to not_raise_error - .and output(/audit for local-transmission: passed/).to_stdout - .and not_to_output.to_stderr + end.to not_raise_error.and not_to_output.to_stderr local_transmission = Cask::CaskLoader.load(cask_path("local-transmission")) cached_location = Cask::Download.new(local_transmission).fetch @@ -156,9 +154,7 @@ describe Cask::Quarantine, :cask do it "does not quarantine Cask audits" do expect do Cask::Cmd::Audit.run("local-transmission", "--download", "--no-quarantine") - end.to not_raise_error - .and output(/audit for local-transmission: passed/).to_stdout - .and not_to_output.to_stderr + end.to not_raise_error.and not_to_output.to_stderr local_transmission = Cask::CaskLoader.load(cask_path("local-transmission")) cached_location = Cask::Download.new(local_transmission).fetch From df8e97fef60ac71337867d87431e304b78ae32c0 Mon Sep 17 00:00:00 2001 From: Issy Long Date: Fri, 31 Mar 2023 01:25:36 +0100 Subject: [PATCH 04/28] Consolidate `add_{warning,error}` methods into one - Specify `strictish: true` in `add_error` to specify that it's not a super big critical error. - These will be shown only if `brew audit --strict` is requested. --- Library/Homebrew/cask/audit.rb | 61 ++++++++++-------------- Library/Homebrew/test/cask/audit_spec.rb | 30 ++++-------- 2 files changed, 35 insertions(+), 56 deletions(-) diff --git a/Library/Homebrew/cask/audit.rb b/Library/Homebrew/cask/audit.rb index aab2793c12..b7bc785c3c 100644 --- a/Library/Homebrew/cask/audit.rb +++ b/Library/Homebrew/cask/audit.rb @@ -81,15 +81,12 @@ module Cask !errors? end - sig { params(message: T.nilable(String), location: T.nilable(String)).void } - def add_error(message, location: nil) - errors << ({ message: message, location: location }) - end + sig { params(message: T.nilable(String), location: T.nilable(String), strictish: T::Boolean).void } + def add_error(message, location: nil, strictish: false) + # Only raise non-critical audits if the user specified `--strict`. + return if strictish && !@strict - sig { params(message: T.nilable(String), location: T.nilable(String)).void } - def add_warning(message, location: nil) - # Warnings are ignored unless `--strict` is passed in which case they're turned into errors. - add_error(message, location: location) if strict? + errors << ({ message: message, location: location }) end def result @@ -195,7 +192,7 @@ module Cask # increases the maintenance burden. return if cask.tap == "homebrew/cask-fonts" - add_warning "Cask should have a description. Please add a `desc` stanza." if cask.desc.blank? + add_error("Cask should have a description. Please add a `desc` stanza.", strictish: true) if cask.desc.blank? end sig { void } @@ -383,8 +380,10 @@ module Cask return unless token_conflicts? return unless core_formula_names.include?(cask.token) - add_warning "possible duplicate, cask token conflicts with Homebrew core formula: " \ - "#{Formatter.url(core_formula_url)}" + add_error( + "possible duplicate, cask token conflicts with Homebrew core formula: #{Formatter.url(core_formula_url)}", + strictish: true, + ) end sig { void } @@ -418,18 +417,19 @@ module Cask add_error "cask token contains version designation '#{match_data[:designation]}'" end - add_warning "cask token mentions launcher" if token.end_with? "launcher" + add_error("cask token mentions launcher", strictish: true) if token.end_with? "launcher" - add_warning "cask token mentions desktop" if token.end_with? "desktop" + add_error("cask token mentions desktop", strictish: true) if token.end_with? "desktop" - add_warning "cask token mentions platform" if token.end_with? "mac", "osx", "macos" + add_error("cask token mentions platform", strictish: true) if token.end_with? "mac", "osx", "macos" - add_warning "cask token mentions architecture" if token.end_with? "x86", "32_bit", "x86_64", "64_bit" + add_error("cask token mentions architecture", strictish: true) if token.end_with? "x86", "32_bit", "x86_64", + "64_bit" frameworks = %w[cocoa qt gtk wx java] return if frameworks.include?(token) || !token.end_with?(*frameworks) - add_warning "cask token mentions framework" + add_error("cask token mentions framework", strictish: true) end sig { void } @@ -449,7 +449,10 @@ module Cask return if cask.url.to_s.include? cask.version.csv.second return if cask.version.csv.third.present? && cask.url.to_s.include?(cask.version.csv.third) - add_warning "Download does not require additional version components. Use `&:short_version` in the livecheck" + add_error( + "Download does not require additional version components. Use `&:short_version` in the livecheck", + strictish: true, + ) end sig { void } @@ -493,7 +496,7 @@ module Cask "#{message} fix the signature of their app." end - add_warning message + add_error(message, strictish: true) when Artifact::Pkg path = downloaded_path next unless path.exist? @@ -501,7 +504,7 @@ module Cask result = system_command("pkgutil", args: ["--check-signature", path], print_stderr: false) unless result.success? - add_warning <<~EOS + add_error(<<~EOS, strictish: true) Signature verification failed: #{result.merged_output} macOS on ARM requires applications to be signed. @@ -513,7 +516,7 @@ module Cask result = system_command("stapler", args: ["validate", path], print_stderr: false) next if result.success? - add_warning <<~EOS + add_error(<<~EOS, strictish: true) Signature verification failed: #{result.merged_output} macOS on ARM requires applications to be signed. @@ -638,16 +641,9 @@ module Cask metadata = SharedAudits.github_repo_data(user, repo) return if metadata.nil? - return unless metadata["archived"] - message = "GitHub repo is archived" - - if cask.discontinued? - add_warning message - else - add_error message - end + add_error("GitHub repo is archived", strictish: cask.discontinued?) end sig { void } @@ -659,16 +655,9 @@ module Cask metadata = SharedAudits.gitlab_repo_data(user, repo) return if metadata.nil? - return unless metadata["archived"] - message = "GitLab repo is archived" - - if cask.discontinued? - add_warning message - else - add_error message - end + add_error("GitLab repo is archived", strictish: cask.discontinued?) end sig { void } diff --git a/Library/Homebrew/test/cask/audit_spec.rb b/Library/Homebrew/test/cask/audit_spec.rb index 873fdb954a..6a32f27030 100644 --- a/Library/Homebrew/test/cask/audit_spec.rb +++ b/Library/Homebrew/test/cask/audit_spec.rb @@ -44,16 +44,6 @@ describe Cask::Audit, :cask do end end - matcher :warn_with do |message| - match do |audit| - include_msg?(audit.errors, message) - end - - failure_message do |audit| - "expected to warn with message #{message.inspect} but #{outcome(audit)}" - end - end - let(:cask) { instance_double(Cask::Cask) } let(:new_cask) { nil } let(:online) { nil } @@ -111,7 +101,7 @@ describe Cask::Audit, :cask do context "when there are no errors and `--strict` is not passed so we should not show anything" do before do - audit.add_warning "eh" + audit.add_error("eh", strictish: true) end it { is_expected.not_to match(/failed/) } @@ -128,7 +118,7 @@ describe Cask::Audit, :cask do context "when there are errors and warnings" do before do audit.add_error "bad" - audit.add_warning "eh" + audit.add_error("eh", strictish: true) end it { is_expected.to match(/failed/) } @@ -139,7 +129,7 @@ describe Cask::Audit, :cask do before do audit.add_error "very bad" - audit.add_warning "a little bit bad" + audit.add_error("a little bit bad", strictish: true) end it { is_expected.to match(/failed/) } @@ -147,7 +137,7 @@ describe Cask::Audit, :cask do context "when there are warnings and `--strict` is not passed" do before do - audit.add_warning "a little bit bad" + audit.add_error("a little bit bad", strictish: true) end it { is_expected.not_to match(/failed/) } @@ -157,7 +147,7 @@ describe Cask::Audit, :cask do let(:strict) { true } before do - audit.add_warning "a little bit bad" + audit.add_error("a little bit bad", strictish: true) end it { is_expected.to match(/failed/) } @@ -501,7 +491,7 @@ describe Cask::Audit, :cask do it "does not fail" do expect(download_double).not_to receive(:fetch) expect(UnpackStrategy).not_to receive(:detect) - expect(run).not_to warn_with(/Audit\.app/) + expect(run).not_to error_with(/Audit\.app/) end end @@ -519,7 +509,7 @@ describe Cask::Audit, :cask do it "does not fail since no extract" do allow(download_double).to receive(:fetch).and_return(Pathname.new("/tmp/test.zip")) allow(UnpackStrategy).to receive(:detect).and_return(nil) - expect(run).not_to warn_with(/Audit\.app/) + expect(run).not_to error_with(/Audit\.app/) end end end @@ -1005,14 +995,14 @@ describe Cask::Audit, :cask do it "warns about duplicates" do expect(audit).to receive(:core_formula_names).and_return(formula_names) - expect(run).to warn_with(/possible duplicate/) + expect(run).to error_with(/possible duplicate/) end end context "when `--strict` is not passed" do it "does not warn about duplicates" do expect(audit).to receive(:core_formula_names).and_return(formula_names) - expect(run).not_to warn_with(/possible duplicate/) + expect(run).not_to error_with(/possible duplicate/) end end end @@ -1086,7 +1076,7 @@ describe Cask::Audit, :cask do let(:new_cask) { false } it "does not warn" do - expect(run).not_to warn_with(/should have a description/) + expect(run).not_to error_with(/should have a description/) end end From e9f233e33398835211237350b881900f1023bdff Mon Sep 17 00:00:00 2001 From: Issy Long Date: Sat, 1 Apr 2023 02:02:23 +0100 Subject: [PATCH 05/28] Remove unused `output_warnings?` Cask audit method --- Library/Homebrew/cask/auditor.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Library/Homebrew/cask/auditor.rb b/Library/Homebrew/cask/auditor.rb index 7a744f2172..85da6e23be 100644 --- a/Library/Homebrew/cask/auditor.rb +++ b/Library/Homebrew/cask/auditor.rb @@ -83,10 +83,6 @@ module Cask audit.errors? end - def output_warnings? - @new_cask.present? || @audit_strict.present? - end - def audit_languages(languages) original_config = cask.config localized_config = original_config.merge(Config.new(explicit: { languages: languages })) From dfa7a60038bf56f06494d6d9bdcd895150fac4b0 Mon Sep 17 00:00:00 2001 From: Razvan Azamfirei Date: Fri, 31 Mar 2023 21:23:09 -0400 Subject: [PATCH 06/28] Feat --- Library/Homebrew/cask/upgrade.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/Library/Homebrew/cask/upgrade.rb b/Library/Homebrew/cask/upgrade.rb index 17c38f43be..cf20a9dd71 100644 --- a/Library/Homebrew/cask/upgrade.rb +++ b/Library/Homebrew/cask/upgrade.rb @@ -40,6 +40,7 @@ module Cask require_sha: nil ) + if quarantine = true if quarantine.nil? outdated_casks = if casks.empty? From c240cf81a48d5a702016f5543ced1d7ccd0f3be9 Mon Sep 17 00:00:00 2001 From: Issy Long Date: Sat, 1 Apr 2023 13:44:26 +0100 Subject: [PATCH 07/28] tests: Remove `--display-failures-only` from `brew audit` cmd --- .github/workflows/tests.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0383948512..4e2bde1be0 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -151,7 +151,7 @@ jobs: run: brew readall --aliases homebrew/core - name: Run brew audit --skip-style on homebrew/core - run: brew audit --skip-style --except=version --display-failures-only --tap=homebrew/core + run: brew audit --skip-style --except=version --tap=homebrew/core cask-audit: name: cask audit @@ -187,10 +187,10 @@ jobs: - name: Run brew audit --skip-style on casks run: | - brew audit --skip-style --except=version --display-failures-only --tap=homebrew/cask - brew audit --skip-style --except=version --display-failures-only --tap=homebrew/cask-drivers - brew audit --skip-style --except=version --display-failures-only --tap=homebrew/cask-fonts - brew audit --skip-style --except=version --display-failures-only --tap=homebrew/cask-versions + brew audit --skip-style --except=version --tap=homebrew/cask + brew audit --skip-style --except=version --tap=homebrew/cask-drivers + brew audit --skip-style --except=version --tap=homebrew/cask-fonts + brew audit --skip-style --except=version --tap=homebrew/cask-versions vendored-gems: name: vendored gems From 53a17b921f714fa2ec38570caa15b168d137fea7 Mon Sep 17 00:00:00 2001 From: Issy Long Date: Mon, 3 Apr 2023 17:23:02 +0100 Subject: [PATCH 08/28] Make `--display-failures-only` help hidden as it's deprecated Co-authored-by: Mike McQuaid --- Library/Homebrew/dev-cmd/audit.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index 7cb204f9cb..50d32e7c34 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -65,7 +65,8 @@ module Homebrew description: "Prefix every line of output with the file or formula name being audited, to " \ "make output easy to grep." switch "--display-failures-only", - description: "Only display casks that fail the audit. This is the default for formulae and casks." + description: "Only display casks that fail the audit. This is the default for formulae and casks.", + hidden: true switch "--skip-style", description: "Skip running non-RuboCop style checks. Useful if you plan on running " \ "`brew style` separately. Enabled by default unless a formula is specified by name." From b1b94187af3dc4194721bc1a15bff1ec7a904eb6 Mon Sep 17 00:00:00 2001 From: Yukai Chou Date: Wed, 5 Apr 2023 03:25:59 +0800 Subject: [PATCH 09/28] tap: tighten `formula_file?(file)` Cask is never a formula. --- Library/Homebrew/tap.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/tap.rb b/Library/Homebrew/tap.rb index 3439ec0c92..fb09122cb7 100644 --- a/Library/Homebrew/tap.rb +++ b/Library/Homebrew/tap.rb @@ -570,7 +570,7 @@ class Tap file = file.expand_path(path) return false unless ruby_file?(file) - file.to_s.start_with?("#{formula_dir}/") + file.to_s.start_with?("#{formula_dir}/") && !file.to_s.start_with?("#{cask_dir}/") end # return true if given path would present a {Cask} file in this {Tap}. From 183fad82a651b2eb58a9739779aee1db441688e1 Mon Sep 17 00:00:00 2001 From: Razvan Azamfirei Date: Wed, 5 Apr 2023 09:28:15 -0400 Subject: [PATCH 10/28] add greedy option --- Library/Homebrew/cask/upgrade.rb | 5 ++++- Library/Homebrew/env_config.rb | 4 ++++ Library/Homebrew/env_config.rbi | 3 +++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/cask/upgrade.rb b/Library/Homebrew/cask/upgrade.rb index cf20a9dd71..d3068f2191 100644 --- a/Library/Homebrew/cask/upgrade.rb +++ b/Library/Homebrew/cask/upgrade.rb @@ -40,9 +40,12 @@ module Cask require_sha: nil ) - if quarantine = true if quarantine.nil? + if Homebrew::EnvConfig.upgrade_greedy? + greedy = true + end + outdated_casks = if casks.empty? Caskroom.casks(config: Config.from_args(args)).select do |cask| cask.outdated?(greedy: greedy, greedy_latest: greedy_latest, diff --git a/Library/Homebrew/env_config.rb b/Library/Homebrew/env_config.rb index 54799a77d5..afc9731ccb 100644 --- a/Library/Homebrew/env_config.rb +++ b/Library/Homebrew/env_config.rb @@ -347,6 +347,10 @@ module Homebrew description: "If set, use Pry for the `brew irb` command.", boolean: true, }, + HOMEBREW_UPGRADE_GREEDY: { + description: "If set, run `--greedy` with all upgrade commands", + boolean: true, + }, HOMEBREW_SIMULATE_MACOS_ON_LINUX: { description: "If set, running Homebrew on Linux will simulate certain macOS code paths. This is useful " \ "when auditing macOS formulae while on Linux.", diff --git a/Library/Homebrew/env_config.rbi b/Library/Homebrew/env_config.rbi index bf67f9c624..f52d381c76 100644 --- a/Library/Homebrew/env_config.rbi +++ b/Library/Homebrew/env_config.rbi @@ -229,6 +229,9 @@ module Homebrew::EnvConfig sig { returns(T::Boolean) } def self.update_to_tag?; end + sig { returns(T::Boolean) } + def self.upgrade_greedy?; end + sig { returns(T::Boolean) } def self.verbose?; end From 28490626fdd7620471376dce6545e44a4fef4ea8 Mon Sep 17 00:00:00 2001 From: Razvan Azamfirei Date: Wed, 5 Apr 2023 09:44:32 -0400 Subject: [PATCH 11/28] style fixes --- Library/Homebrew/cask/upgrade.rb | 4 +--- Library/Homebrew/dev-cmd/bump-cask-pr.rb | 2 +- Library/Homebrew/env_config.rb | 5 +---- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/Library/Homebrew/cask/upgrade.rb b/Library/Homebrew/cask/upgrade.rb index d3068f2191..41c52954f9 100644 --- a/Library/Homebrew/cask/upgrade.rb +++ b/Library/Homebrew/cask/upgrade.rb @@ -42,9 +42,7 @@ module Cask quarantine = true if quarantine.nil? - if Homebrew::EnvConfig.upgrade_greedy? - greedy = true - end + greedy = true if Homebrew::EnvConfig.upgrade_greedy? outdated_casks = if casks.empty? Caskroom.casks(config: Config.from_args(args)).select do |cask| diff --git a/Library/Homebrew/dev-cmd/bump-cask-pr.rb b/Library/Homebrew/dev-cmd/bump-cask-pr.rb index be951dadbd..fe6303d764 100644 --- a/Library/Homebrew/dev-cmd/bump-cask-pr.rb +++ b/Library/Homebrew/dev-cmd/bump-cask-pr.rb @@ -84,7 +84,7 @@ module Homebrew Cask::DSL::Version.new(new_version) end - new_hash = unless (new_hash = args.sha256).nil? + new_hash = unless (new_hash = args.sha265).nil? raise UsageError, "`--sha256` must not be empty." if new_hash.blank? ["no_check", ":no_check"].include?(new_hash) ? :no_check : new_hash diff --git a/Library/Homebrew/env_config.rb b/Library/Homebrew/env_config.rb index afc9731ccb..e3cfc9d716 100644 --- a/Library/Homebrew/env_config.rb +++ b/Library/Homebrew/env_config.rb @@ -239,9 +239,6 @@ module Homebrew HOMEBREW_GITHUB_PACKAGES_USER: { description: "Use this username when accessing the GitHub Packages Registry (where bottles may be stored).", }, - HOMEBREW_GREEDY: { - description: "Pass this value to brew upgrade greedy.", - }, HOMEBREW_INSTALL_BADGE: { description: "Print this text before the installation summary of each successful build.", default_text: 'The "Beer Mug" emoji.', @@ -347,7 +344,7 @@ module Homebrew description: "If set, use Pry for the `brew irb` command.", boolean: true, }, - HOMEBREW_UPGRADE_GREEDY: { + HOMEBREW_UPGRADE_GREEDY: { description: "If set, run `--greedy` with all upgrade commands", boolean: true, }, From 200b5cad6a6d47f683624bfdc51cd994977ae4fd Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Wed, 5 Apr 2023 10:06:45 -0700 Subject: [PATCH 12/28] Minor YARD improvements --- .github/workflows/docs.yml | 2 +- Library/Homebrew/.yardopts | 1 + Library/Homebrew/utils/inreplace.rb | 13 ++++++------- .../yard/templates/default/docstring/html/setup.rb | 6 +++++- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 88903a17a4..4d5a5ed321 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -64,4 +64,4 @@ jobs: - name: Process rubydoc comments working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}/Library/Homebrew - run: bundle exec yard doc --plugin sorbet --no-output --fail-on-warning + run: bundle exec yard doc --no-output --fail-on-warning diff --git a/Library/Homebrew/.yardopts b/Library/Homebrew/.yardopts index ef2b4836c7..f9ca1591d5 100644 --- a/Library/Homebrew/.yardopts +++ b/Library/Homebrew/.yardopts @@ -2,6 +2,7 @@ --main README.md --markup markdown --no-private +--plugin sorbet --load yard/ignore_directives.rb --template-path yard/templates --exclude test/ diff --git a/Library/Homebrew/utils/inreplace.rb b/Library/Homebrew/utils/inreplace.rb index 9763760258..50ff78f80b 100644 --- a/Library/Homebrew/utils/inreplace.rb +++ b/Library/Homebrew/utils/inreplace.rb @@ -29,14 +29,13 @@ module Utils # defined by the formula, as only `HOMEBREW_PREFIX` is available # in the {DATAPatch embedded patch}. # - # `inreplace` supports regular expressions: - #
inreplace "somefile.cfg", /look[for]what?/, "replace by #{bin}/tool"
+ # @example `inreplace` supports regular expressions: + # inreplace "somefile.cfg", /look[for]what?/, "replace by #{bin}/tool" # - # `inreplace` supports blocks: - #
inreplace "Makefile" do |s|
-    #   s.gsub! "/usr/local", HOMEBREW_PREFIX.to_s
-    # end
-    # 
+ # @example `inreplace` supports blocks: + # inreplace "Makefile" do |s| + # s.gsub! "/usr/local", HOMEBREW_PREFIX.to_s + # end # # @see StringInreplaceExtension # @api public diff --git a/Library/Homebrew/yard/templates/default/docstring/html/setup.rb b/Library/Homebrew/yard/templates/default/docstring/html/setup.rb index 6d07ea8198..27272f9ff6 100644 --- a/Library/Homebrew/yard/templates/default/docstring/html/setup.rb +++ b/Library/Homebrew/yard/templates/default/docstring/html/setup.rb @@ -1,7 +1,10 @@ -# typed: false +# typed: true # frozen_string_literal: true def init + # `sorbet` is available transitively through the `yard-sorbet` plugin, but we're + # outside of the standalone sorbet config, so `checked` is enabled by default + T.bind(self, YARD::Templates::Template, checked: false) super return if sections.empty? @@ -10,5 +13,6 @@ def init end def internal + T.bind(self, YARD::Templates::Template, checked: false) erb(:internal) if object.has_tag?(:api) && object.tag(:api).text == "internal" end From c6fdfa3258bf7eb7a66c64702e290c7202f47caa Mon Sep 17 00:00:00 2001 From: Colin Dean Date: Tue, 4 Apr 2023 23:55:57 -0400 Subject: [PATCH 13/28] Import doc "How To Organize AGM" from homebrew-governance-private The PLC and members workshopped and reviewed this based on past AGMs, especially the 2023 meeting. This has some small formatting-only changes compared ot the H-G-P version due to Markdownlint rules on this public repository. I'll port these changes to the private repo after merging. --- docs/How-To-Organize-AGM.md | 162 ++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 docs/How-To-Organize-AGM.md diff --git a/docs/How-To-Organize-AGM.md b/docs/How-To-Organize-AGM.md new file mode 100644 index 0000000000..cca2a77fbe --- /dev/null +++ b/docs/How-To-Organize-AGM.md @@ -0,0 +1,162 @@ +# How to Organize AGM + +AGM is our combination of business meeting, yearly work planning session, and opportunity to meet others in our international team in person. + +This document is a _guide_ that assumes that the meeting will be held in person. +If a situation occurs that prevents that, it is acceptable to execute it virtually, as was done in 2021 and 2022 during the COVID-19 pandemic. + + + +* [Roles](#roles) +* [Logistics Timeline](#logistics-timeline) + * [Three months prior](#three-months-prior) + * [Two months prior](#two-months-prior) + * [Four weeks prior](#four-weeks-prior) + * [Three weeks prior](#three-weeks-prior) + * [Two weeks prior](#two-weeks-prior) + * [10 days prior](#10-days-prior) + * [One week prior](#one-week-prior) + * [Day before](#day-before) + * [Day-of](#day-of) +* [Pre-planning](#pre-planning) + * [Finding a Meeting Venue](#finding-a-meeting-venue) + * [Who Qualifies For AGM Travel Assistance](#who-qualifies-for-agm-travel-assistance) +* [Ideas for future AGMs](#ideas-for-future-agms) + * [Meeting enhancements](#meeting-enhancements) + * [Day-of enhancements](#day-of-enhancements) + + + +## Roles + +Expected participants: + +|Who|Role| +|---|---| +|Project Leadership Committee (PLC)|Should be physically present if possible, dialed-in if not. Several members must be present in person to run the event. Several members, regardless, needed to provide content for meeting.| +|Project Leader (PL)|Should be physically present if possible, dialed-in if not. Regardless, needed to provide content for meeting.| +|Technology Steering Committee (TSC)|Should be physically present if possible, dialed-in if not. Regardless, needed to provide content for meeting.| +|Members|Should dial-in or participate in person if possible.| + +PLC members' roles of responsibility for planning and execution: + +|Who|Role| +|---|---| +|Logistics Coordinator (LC)|Coordinates with meeting venue, restaurants, members, committees, vendors| +|Agenda Coordinator (AC)|Coordinates agenda and content to be presented| +|Technology Coordinator (TC)|Coordinates video conference audiovisual setup| + +:information_source: _(A person may have more than one role but one person should not have all roles.)_ + +## Logistics Timeline + +Past practice and future intent is for AGM to coincide with [FOSDEM](https://fosdem.org "Free and Open Source Developers European Meeting"), which is held in Brussels, Belgium annually typically on the Saturday and Sunday of the fifth ISO-8601 week of the calendar year, calculable with: + + ruby -rdate -e "s=ARGV[0].to_i;s.upto(s+4).map{|y|Date.commercial(y,5,6)}.each{|y|puts [y,y+1].join(' - ')}" 2024 + +AGM should be held on the Friday before or the Monday following FOSDEM. + +:information_source: _Regenerate the dates for the WHEN lines in the next several headers +using this quick command:_ + + ruby -rdate -e "YEAR=ARGV[0].to_i;puts ([[44,YEAR-1],[49,YEAR-1]]+(1.upto(4).map{|wk|[wk, YEAR]})).map{|wk,yr|Date.commercial(yr,wk).to_s}" 2024 + +### Three months prior + +**When:** Week 44 of YEAR-1 :date: `2023-10-30` + +* [ ] LC: Seek venue through previous contacts or RFP. +* [ ] PLC: Notify members of eligibility to attend AGM, with date to be determined. + * This is primarily to enable members to begin planning travel by + asking for time off, requesting employer reimbursement, + arranging childcare or pet sitters, + [applying for a visa](https://5195.f2w.bosa.be/en/themes/entry/border-control/visa/visa-type-c) + which may [take 2–7 weeks](https://dofi.ibz.be/en/themes/third-country-nationals/short-stay/processing-time-visa-application), + etc. + +### Two months prior + +**When:** Week 49 of YEAR-1 :date: `2023-12-04` + +* [ ] LC: Seek informal count of members intending to attend in-person. +* [ ] PL: Review maintainer activity per [Governance/Maintainers](Homebrew-Governance.md#8-maintainers). +* [ ] PLC: Determine travel assistance budget. +* [ ] PLC: Open travel assistance pre-approval process. + +### Four weeks prior + +**When:** Week 1 of YEAR :date: `2024-01-01` + +* [ ] PLC: Solicit changes to [Homebrew Governance](Homebrew-Governance.md) in the form of PRs on the `homebrew-governance-private` repo. + +### Three weeks prior + +**When:** Week 2 of YEAR :date: `2024-01-08` + +* [ ] PLC: Close travel assistance pre-approval process. + +### Two weeks prior + +**When:** Week 3 of YEAR :date: `2024-01-15` + +* [ ] AC: Create agenda, solicit agenda items from PLC and TSC. +* [ ] LC: Seek committed member attendance and dietary requirements for each. +* [ ] PLC: Close proposals for new Governance changes. + +### 10 days prior + +**When:** Week 4 of YEAR :date: `2024-01-22` + +* [ ] PLC: Resolve all open Governance PRs, roll-up changes, and open PR with changes to `docs/Homebrew-Governance.md` on `homebrew/brew`. + +### One week prior + +**When:** Week 4 of YEAR :date: `2024-01-22` + +* [ ] PLC: Open voting for PLC, PL, and Governance changes. +* [ ] AC: Solicit agenda items from membership. +* [ ] LC: Secure a venue and reservation for dinner + +### Day before + +* [ ] LC: Confirm reservation count for dinner with attendees +* [ ] LC: Hand-off venue AV contact to TC + +### Day-of + +* [ ] LC: Confirm reservation count for dinner with venue +* [ ] TC: Connect to video conference, ensure audiovisual equipment is ready and appropriately placed and leveled periodically +* [ ] AC: Keep the meeting paced to the agenda, keep time for timeboxed discussions, cut people off if they're talking too long, ensure remote attendees can get a word in + +## Pre-planning + +### Finding a Meeting Venue + +In the past, PLC hosted the AGM at the +[THON Hotel Brussels City Centre](https://www.thonhotels.com/conference/belgium/brussels/thon-hotel-brussels-city-centre/?Persons=20) +and arranged for a room block checking in the day before FOSDEM and AGM weekend, generally on Friday, and checking out the day after, generally Tuesday when the AGM is Monday. + +### Who Qualifies For AGM Travel Assistance + +Travel assistance is available for AGM participants who are expected to attend the AGM in-person. +Those who have employers able to cover all or a part of the costs of attending FOSDEM should exhaust that +source of funding before seeking Homebrew funding. + +PLC, TSC, PL and maintainers can expect to have all reasonable, in-policy expenses covered while members will be considered on a case-by-case basis. + +See also the [Reimbursement Policy](Expense-and-Reimbursement-Policy.md#travel) for process and details on what is covered. +It is important that all attendees expecting reimbursement stay in-policy. + +## Ideas for future AGMs + +### Meeting enhancements + +* Captioning or transcription, or both - [White Coat Captioning](https://whitecoatcaptioning.com) could handle the live captioning and provide us that for a transcript. +* Separate meeting runner + * Keep PL ideally focused on content and not agenda or tracking who's asked to speak + * Should be a PLC member who is not the AC, LC, or TC + * Should be someone happy and willing to cut people off mid-sentence and, assertively but in a friendly manner, stop conversations that are not running to time + +### Day-of enhancements + +* Track dietary requirements centrally for in-person participants From bd94eab3498ab981799027a6a881c9037f1116ee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Apr 2023 18:58:03 +0000 Subject: [PATCH 14/28] build(deps): bump addressable from 2.8.2 to 2.8.3 in /Library/Homebrew Bumps [addressable](https://github.com/sporkmonger/addressable) from 2.8.2 to 2.8.3. - [Release notes](https://github.com/sporkmonger/addressable/releases) - [Changelog](https://github.com/sporkmonger/addressable/blob/main/CHANGELOG.md) - [Commits](https://github.com/sporkmonger/addressable/compare/addressable-2.8.2...addressable-2.8.3) --- updated-dependencies: - dependency-name: addressable dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Library/Homebrew/Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/Gemfile.lock b/Library/Homebrew/Gemfile.lock index 283770a591..e7e42c144d 100644 --- a/Library/Homebrew/Gemfile.lock +++ b/Library/Homebrew/Gemfile.lock @@ -7,7 +7,7 @@ GEM minitest (>= 5.1) tzinfo (~> 2.0) zeitwerk (~> 2.3) - addressable (2.8.2) + addressable (2.8.3) public_suffix (>= 2.0.2, < 6.0) ast (2.4.2) bindata (2.4.15) From 60ae89c2454640ee95505a9b759ad5e530d0c0a5 Mon Sep 17 00:00:00 2001 From: BrewTestBot <1589480+BrewTestBot@users.noreply.github.com> Date: Wed, 5 Apr 2023 19:04:35 +0000 Subject: [PATCH 15/28] brew vendor-gems: commit updates. --- Library/Homebrew/vendor/bundle/bundler/setup.rb | 2 +- .../data/unicode.data | Bin .../lib/addressable.rb | 0 .../lib/addressable/idna.rb | 0 .../lib/addressable/idna/native.rb | 0 .../lib/addressable/idna/pure.rb | 0 .../lib/addressable/template.rb | 9 +++------ .../lib/addressable/uri.rb | 0 .../lib/addressable/version.rb | 2 +- 9 files changed, 5 insertions(+), 8 deletions(-) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{addressable-2.8.2 => addressable-2.8.3}/data/unicode.data (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{addressable-2.8.2 => addressable-2.8.3}/lib/addressable.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{addressable-2.8.2 => addressable-2.8.3}/lib/addressable/idna.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{addressable-2.8.2 => addressable-2.8.3}/lib/addressable/idna/native.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{addressable-2.8.2 => addressable-2.8.3}/lib/addressable/idna/pure.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{addressable-2.8.2 => addressable-2.8.3}/lib/addressable/template.rb (99%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{addressable-2.8.2 => addressable-2.8.3}/lib/addressable/uri.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{addressable-2.8.2 => addressable-2.8.3}/lib/addressable/version.rb (98%) diff --git a/Library/Homebrew/vendor/bundle/bundler/setup.rb b/Library/Homebrew/vendor/bundle/bundler/setup.rb index 20237573a7..c24ec0100a 100644 --- a/Library/Homebrew/vendor/bundle/bundler/setup.rb +++ b/Library/Homebrew/vendor/bundle/bundler/setup.rb @@ -30,7 +30,7 @@ $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/zeitwerk-2.6.7/lib") $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/activesupport-6.1.7.3/lib") $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/public_suffix-5.0.1/lib") -$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/addressable-2.8.2/lib") +$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/addressable-2.8.3/lib") $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/ast-2.4.2/lib") $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/bindata-2.4.15/lib") $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/universal-darwin-21/#{Gem.extension_api_version}/msgpack-1.7.0") diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.2/data/unicode.data b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.3/data/unicode.data similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.2/data/unicode.data rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.3/data/unicode.data diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.2/lib/addressable.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.3/lib/addressable.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.2/lib/addressable.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.3/lib/addressable.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.2/lib/addressable/idna.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.3/lib/addressable/idna.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.2/lib/addressable/idna.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.3/lib/addressable/idna.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.2/lib/addressable/idna/native.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.3/lib/addressable/idna/native.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.2/lib/addressable/idna/native.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.3/lib/addressable/idna/native.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.2/lib/addressable/idna/pure.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.3/lib/addressable/idna/pure.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.2/lib/addressable/idna/pure.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.3/lib/addressable/idna/pure.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.2/lib/addressable/template.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.3/lib/addressable/template.rb similarity index 99% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.2/lib/addressable/template.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.3/lib/addressable/template.rb index 42cbf7cc56..bc5204154f 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.2/lib/addressable/template.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.3/lib/addressable/template.rb @@ -896,19 +896,16 @@ module Addressable # # @return [Hash, Array, String] The normalized values def normalize_value(value) - unless value.is_a?(Hash) - value = value.respond_to?(:to_ary) ? value.to_ary : value.to_str - end - # Handle unicode normalization - if value.kind_of?(Array) - value.map! { |val| normalize_value(val) } + if value.respond_to?(:to_ary) + value.to_ary.map! { |val| normalize_value(val) } elsif value.kind_of?(Hash) value = value.inject({}) { |acc, (k, v)| acc[normalize_value(k)] = normalize_value(v) acc } else + value = value.to_s if !value.kind_of?(String) if value.encoding != Encoding::UTF_8 value = value.dup.force_encoding(Encoding::UTF_8) end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.2/lib/addressable/uri.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.3/lib/addressable/uri.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.2/lib/addressable/uri.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.3/lib/addressable/uri.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.2/lib/addressable/version.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.3/lib/addressable/version.rb similarity index 98% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.2/lib/addressable/version.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.3/lib/addressable/version.rb index 6e7fb78d9e..35551b90a6 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.2/lib/addressable/version.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.3/lib/addressable/version.rb @@ -23,7 +23,7 @@ if !defined?(Addressable::VERSION) module VERSION MAJOR = 2 MINOR = 8 - TINY = 2 + TINY = 3 STRING = [MAJOR, MINOR, TINY].join('.') end From e7e80ad8afa6a40815f3676315e72c7776751d5e Mon Sep 17 00:00:00 2001 From: BrewTestBot <1589480+BrewTestBot@users.noreply.github.com> Date: Wed, 5 Apr 2023 19:10:42 +0000 Subject: [PATCH 16/28] Update RBI files for addressable. Autogenerated by the [vendor-gems](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/vendor-gems.yml) workflow. --- .../rbi/gems/{addressable@2.8.2.rbi => addressable@2.8.3.rbi} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Library/Homebrew/sorbet/rbi/gems/{addressable@2.8.2.rbi => addressable@2.8.3.rbi} (100%) diff --git a/Library/Homebrew/sorbet/rbi/gems/addressable@2.8.2.rbi b/Library/Homebrew/sorbet/rbi/gems/addressable@2.8.3.rbi similarity index 100% rename from Library/Homebrew/sorbet/rbi/gems/addressable@2.8.2.rbi rename to Library/Homebrew/sorbet/rbi/gems/addressable@2.8.3.rbi From 785991773ffd16f4be2a30cd2a907f366bcc0433 Mon Sep 17 00:00:00 2001 From: Issy Long Date: Wed, 5 Apr 2023 21:32:17 +0100 Subject: [PATCH 17/28] docs/governance/2023-agm-minutes: Add brief summary of talking points --- docs/governance/2023-agm-minutes.md | 45 +++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 docs/governance/2023-agm-minutes.md diff --git a/docs/governance/2023-agm-minutes.md b/docs/governance/2023-agm-minutes.md new file mode 100644 index 0000000000..9e3e2e3f24 --- /dev/null +++ b/docs/governance/2023-agm-minutes.md @@ -0,0 +1,45 @@ +# Homebrew Annual General Meeting 2022 + +## Minutes + +- 09:10 Call to order + +## Reports + +- 09:15 Project Leader Report (15 min, Mike McQuaid) +- 09:40 Project Leadership Committee Report (15 min, Sean Molenaar) +- 10:00 Technical Steering Commitee Report (15 min, Michka Popoff) + +## Election Results + +- 10:00 PL Voting Results (5 min, Issy Long) + - Mike McQuaid was re-elected. + +- 10:05 PLC Voting Results (5 min, Sean Molenaar because Issy felt weird announcing their own election) + - Issy Long and Jon Chang were re-elected and Colin Dean was newly elected. + - Commiserations to George Adams who was not elected. + +- 10:10 Governance Changes Voting Results (5 min, Issy Long) + - The governance changes () passed. + +## Member presentations and discussions (11:00-12:00 and 13:30-15:00) + +- ARM on Linux (Michka Popoff) +- Install from API (Rylan Polster) +- Homebrew on Linux (Patrick Linanne and Bo Anderson) +- CI infrastructure (Rui Chen) +- Security initiatives (Patrick Linanne) +- Formula licenses (Rui Chen) +- GitHub authentication security improvements (Colin Dean) +- Improvements to autobumping formulae and casks (Rui Chen) +- Formalizing the reimbursement process (Colin Dean) +- Homebrew Mastodon account (Mike McQuaid) +- InfluxDB analytics (Mike McQuaid) +- Security posture improvements, potentially making a security-focused volunteer group (Mike McQuaid) + +## Hackathon (undocumented, 15:00-17:00) + +## Adjournment + +- Final remarks, thanks for coming (Issy Long) +- 17:00 Meeting finished. From 1098cb6a7d2ddb62302c1f09358c950c0fcdb006 Mon Sep 17 00:00:00 2001 From: Yukai Chou Date: Thu, 6 Apr 2023 04:59:55 +0800 Subject: [PATCH 18/28] avoid duplicating logic --- Library/Homebrew/tap.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Library/Homebrew/tap.rb b/Library/Homebrew/tap.rb index fb09122cb7..b96e878d0c 100644 --- a/Library/Homebrew/tap.rb +++ b/Library/Homebrew/tap.rb @@ -561,7 +561,7 @@ class Tap file.extname == ".rb" end - # return true if given path would present a {Formula} file in this {Tap}. + # returns true if given path would present a {Formula} file in this {Tap}. # accepts both absolute path and relative path (relative to this {Tap}'s path) # @private sig { params(file: T.any(String, Pathname)).returns(T::Boolean) } @@ -569,11 +569,12 @@ class Tap file = Pathname.new(file) unless file.is_a? Pathname file = file.expand_path(path) return false unless ruby_file?(file) + return false if cask_pathname?(file) - file.to_s.start_with?("#{formula_dir}/") && !file.to_s.start_with?("#{cask_dir}/") + file.to_s.start_with?("#{formula_dir}/") end - # return true if given path would present a {Cask} file in this {Tap}. + # returns true if given path would present a {Cask} file in this {Tap}. # accepts both absolute path and relative path (relative to this {Tap}'s path) # @private sig { params(file: T.any(String, Pathname)).returns(T::Boolean) } From 16c81d7a55b56519d3235c2e29290b7082b7ca72 Mon Sep 17 00:00:00 2001 From: Yukai Chou Date: Thu, 6 Apr 2023 05:00:21 +0800 Subject: [PATCH 19/28] tighten `tap.formula_files` similarly --- Library/Homebrew/tap.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/tap.rb b/Library/Homebrew/tap.rb index b96e878d0c..54c6ce367c 100644 --- a/Library/Homebrew/tap.rb +++ b/Library/Homebrew/tap.rb @@ -498,7 +498,7 @@ class Tap formula_dir.find else formula_dir.children - end.select(&method(:ruby_file?)) + end.select(&method(:formula_file?)) else [] end From 0cfc4ab1e8bca66bbc08cae6b964a348e48116ec Mon Sep 17 00:00:00 2001 From: Yukai Chou Date: Thu, 6 Apr 2023 05:03:56 +0800 Subject: [PATCH 20/28] fixup! avoid duplicating logic --- Library/Homebrew/tap.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/tap.rb b/Library/Homebrew/tap.rb index 54c6ce367c..b7c12b5b20 100644 --- a/Library/Homebrew/tap.rb +++ b/Library/Homebrew/tap.rb @@ -569,7 +569,7 @@ class Tap file = Pathname.new(file) unless file.is_a? Pathname file = file.expand_path(path) return false unless ruby_file?(file) - return false if cask_pathname?(file) + return false if cask_file?(file) file.to_s.start_with?("#{formula_dir}/") end From d636d2de372749306ec13efc0c93d54dddb9236f Mon Sep 17 00:00:00 2001 From: Issy Long Date: Tue, 4 Apr 2023 17:22:00 +0100 Subject: [PATCH 21/28] Apply suggestions from review comments - Rename `strictish` to `strict_only` in `add_error` method. - Return just `errors`, a Set, not `{ errors: errors }`, a Hash, from `Auditor.audit`. --- Library/Homebrew/cask/audit.rb | 34 ++++++++++---------- Library/Homebrew/cask/auditor.rb | 2 +- Library/Homebrew/cask/cmd/audit.rb | 2 +- Library/Homebrew/dev-cmd/audit.rb | 4 +-- Library/Homebrew/test/cask/audit_spec.rb | 10 +++--- Library/Homebrew/test/cask/cmd/audit_spec.rb | 2 +- 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Library/Homebrew/cask/audit.rb b/Library/Homebrew/cask/audit.rb index b7bc785c3c..b6597bf36b 100644 --- a/Library/Homebrew/cask/audit.rb +++ b/Library/Homebrew/cask/audit.rb @@ -81,10 +81,10 @@ module Cask !errors? end - sig { params(message: T.nilable(String), location: T.nilable(String), strictish: T::Boolean).void } - def add_error(message, location: nil, strictish: false) + sig { params(message: T.nilable(String), location: T.nilable(String), strict_only: T::Boolean).void } + def add_error(message, location: nil, strict_only: false) # Only raise non-critical audits if the user specified `--strict`. - return if strictish && !@strict + return if strict_only && !@strict errors << ({ message: message, location: location }) end @@ -192,7 +192,7 @@ module Cask # increases the maintenance burden. return if cask.tap == "homebrew/cask-fonts" - add_error("Cask should have a description. Please add a `desc` stanza.", strictish: true) if cask.desc.blank? + add_error("Cask should have a description. Please add a `desc` stanza.", strict_only: true) if cask.desc.blank? end sig { void } @@ -382,7 +382,7 @@ module Cask add_error( "possible duplicate, cask token conflicts with Homebrew core formula: #{Formatter.url(core_formula_url)}", - strictish: true, + strict_only: true, ) end @@ -417,19 +417,19 @@ module Cask add_error "cask token contains version designation '#{match_data[:designation]}'" end - add_error("cask token mentions launcher", strictish: true) if token.end_with? "launcher" + add_error("cask token mentions launcher", strict_only: true) if token.end_with? "launcher" - add_error("cask token mentions desktop", strictish: true) if token.end_with? "desktop" + add_error("cask token mentions desktop", strict_only: true) if token.end_with? "desktop" - add_error("cask token mentions platform", strictish: true) if token.end_with? "mac", "osx", "macos" + add_error("cask token mentions platform", strict_only: true) if token.end_with? "mac", "osx", "macos" - add_error("cask token mentions architecture", strictish: true) if token.end_with? "x86", "32_bit", "x86_64", - "64_bit" + add_error("cask token mentions architecture", strict_only: true) if token.end_with? "x86", "32_bit", "x86_64", + "64_bit" frameworks = %w[cocoa qt gtk wx java] return if frameworks.include?(token) || !token.end_with?(*frameworks) - add_error("cask token mentions framework", strictish: true) + add_error("cask token mentions framework", strict_only: true) end sig { void } @@ -451,7 +451,7 @@ module Cask add_error( "Download does not require additional version components. Use `&:short_version` in the livecheck", - strictish: true, + strict_only: true, ) end @@ -496,7 +496,7 @@ module Cask "#{message} fix the signature of their app." end - add_error(message, strictish: true) + add_error(message, strict_only: true) when Artifact::Pkg path = downloaded_path next unless path.exist? @@ -504,7 +504,7 @@ module Cask result = system_command("pkgutil", args: ["--check-signature", path], print_stderr: false) unless result.success? - add_error(<<~EOS, strictish: true) + add_error(<<~EOS, strict_only: true) Signature verification failed: #{result.merged_output} macOS on ARM requires applications to be signed. @@ -516,7 +516,7 @@ module Cask result = system_command("stapler", args: ["validate", path], print_stderr: false) next if result.success? - add_error(<<~EOS, strictish: true) + add_error(<<~EOS, strict_only: true) Signature verification failed: #{result.merged_output} macOS on ARM requires applications to be signed. @@ -643,7 +643,7 @@ module Cask return if metadata.nil? return unless metadata["archived"] - add_error("GitHub repo is archived", strictish: cask.discontinued?) + add_error("GitHub repo is archived", strict_only: cask.discontinued?) end sig { void } @@ -657,7 +657,7 @@ module Cask return if metadata.nil? return unless metadata["archived"] - add_error("GitLab repo is archived", strictish: cask.discontinued?) + add_error("GitLab repo is archived", strict_only: cask.discontinued?) end sig { void } diff --git a/Library/Homebrew/cask/auditor.rb b/Library/Homebrew/cask/auditor.rb index 85da6e23be..c631f1e5b7 100644 --- a/Library/Homebrew/cask/auditor.rb +++ b/Library/Homebrew/cask/auditor.rb @@ -70,7 +70,7 @@ module Cask errors += audit.errors end - { errors: errors } + errors end private diff --git a/Library/Homebrew/cask/cmd/audit.rb b/Library/Homebrew/cask/cmd/audit.rb index 59d759f8d2..57ba90e369 100644 --- a/Library/Homebrew/cask/cmd/audit.rb +++ b/Library/Homebrew/cask/cmd/audit.rb @@ -60,7 +60,7 @@ module Cask except: [], ) - failed_casks = results.reject { |_, result| result[:errors].empty? }.map(&:first) + failed_casks = results.reject { |_, result| result.empty? }.map(&:first) return if failed_casks.empty? raise CaskError, "audit failed for casks: #{failed_casks.join(" ")}" diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index 50d32e7c34..bd919b84bb 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -266,11 +266,11 @@ module Homebrew ) end - failed_casks = cask_results.reject { |_, result| result[:errors].empty? } + failed_casks = cask_results.reject { |_, result| result.empty? } cask_count = failed_casks.count - cask_problem_count = failed_casks.sum { |_, result| result[:warnings].count + result[:errors].count } + cask_problem_count = failed_casks.sum { |_, result| result.count } new_formula_problem_count += new_formula_problem_lines.count total_problems_count = problem_count + new_formula_problem_count + cask_problem_count + tap_problem_count diff --git a/Library/Homebrew/test/cask/audit_spec.rb b/Library/Homebrew/test/cask/audit_spec.rb index 6a32f27030..e71514440c 100644 --- a/Library/Homebrew/test/cask/audit_spec.rb +++ b/Library/Homebrew/test/cask/audit_spec.rb @@ -101,7 +101,7 @@ describe Cask::Audit, :cask do context "when there are no errors and `--strict` is not passed so we should not show anything" do before do - audit.add_error("eh", strictish: true) + audit.add_error("eh", strict_only: true) end it { is_expected.not_to match(/failed/) } @@ -118,7 +118,7 @@ describe Cask::Audit, :cask do context "when there are errors and warnings" do before do audit.add_error "bad" - audit.add_error("eh", strictish: true) + audit.add_error("eh", strict_only: true) end it { is_expected.to match(/failed/) } @@ -129,7 +129,7 @@ describe Cask::Audit, :cask do before do audit.add_error "very bad" - audit.add_error("a little bit bad", strictish: true) + audit.add_error("a little bit bad", strict_only: true) end it { is_expected.to match(/failed/) } @@ -137,7 +137,7 @@ describe Cask::Audit, :cask do context "when there are warnings and `--strict` is not passed" do before do - audit.add_error("a little bit bad", strictish: true) + audit.add_error("a little bit bad", strict_only: true) end it { is_expected.not_to match(/failed/) } @@ -147,7 +147,7 @@ describe Cask::Audit, :cask do let(:strict) { true } before do - audit.add_error("a little bit bad", strictish: true) + audit.add_error("a little bit bad", strict_only: true) end it { is_expected.to match(/failed/) } diff --git a/Library/Homebrew/test/cask/cmd/audit_spec.rb b/Library/Homebrew/test/cask/cmd/audit_spec.rb index 12728b4777..604f281f02 100644 --- a/Library/Homebrew/test/cask/cmd/audit_spec.rb +++ b/Library/Homebrew/test/cask/cmd/audit_spec.rb @@ -6,7 +6,7 @@ require "cask/auditor" describe Cask::Cmd::Audit, :cask do let(:cask) { Cask::Cask.new("cask") } let(:cask_with_many_languages) { Cask::CaskLoader.load(cask_path("with-many-languages")) } - let(:result) { { warnings: Set.new, errors: Set.new } } + let(:result) { Set.new } describe "selection of Casks to audit" do it "audits all Casks if no tokens are given" do From 87b4f1f396bbfcf59c8d264b30b825114ee7dbd6 Mon Sep 17 00:00:00 2001 From: Razvan Azamfirei Date: Wed, 5 Apr 2023 19:26:20 -0400 Subject: [PATCH 22/28] Update env_config.rb --- Library/Homebrew/env_config.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/env_config.rb b/Library/Homebrew/env_config.rb index e3cfc9d716..a7e5720be0 100644 --- a/Library/Homebrew/env_config.rb +++ b/Library/Homebrew/env_config.rb @@ -345,7 +345,7 @@ module Homebrew boolean: true, }, HOMEBREW_UPGRADE_GREEDY: { - description: "If set, run `--greedy` with all upgrade commands", + description: "If set, run `--greedy` with all upgrade commands.", boolean: true, }, HOMEBREW_SIMULATE_MACOS_ON_LINUX: { From acc598fdc935922929912329a0597585049fa30b Mon Sep 17 00:00:00 2001 From: Razvan Azamfirei Date: Wed, 5 Apr 2023 19:29:57 -0400 Subject: [PATCH 23/28] Update env_config.rb Co-authored-by: Mike McQuaid --- Library/Homebrew/env_config.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/env_config.rb b/Library/Homebrew/env_config.rb index a7e5720be0..b662859733 100644 --- a/Library/Homebrew/env_config.rb +++ b/Library/Homebrew/env_config.rb @@ -345,7 +345,7 @@ module Homebrew boolean: true, }, HOMEBREW_UPGRADE_GREEDY: { - description: "If set, run `--greedy` with all upgrade commands.", + description: ""If set, pass `--greedy` to all cask upgrade commands.", boolean: true, }, HOMEBREW_SIMULATE_MACOS_ON_LINUX: { From 22eb43ca373d64d2c31606b3a46dae908444f9c2 Mon Sep 17 00:00:00 2001 From: Razvan Azamfirei Date: Wed, 5 Apr 2023 20:07:58 -0400 Subject: [PATCH 24/28] syntax fix --- Library/Homebrew/env_config.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/env_config.rb b/Library/Homebrew/env_config.rb index b662859733..94a3ca7f96 100644 --- a/Library/Homebrew/env_config.rb +++ b/Library/Homebrew/env_config.rb @@ -345,7 +345,7 @@ module Homebrew boolean: true, }, HOMEBREW_UPGRADE_GREEDY: { - description: ""If set, pass `--greedy` to all cask upgrade commands.", + description: "If set, pass `--greedy` to all cask upgrade commands.", boolean: true, }, HOMEBREW_SIMULATE_MACOS_ON_LINUX: { From fbf474a3fd107b636eb397b0aa247f7e03f2dc72 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Fri, 31 Mar 2023 21:35:58 +0200 Subject: [PATCH 25/28] Add `curl_head` method. --- Library/Homebrew/download_strategy.rb | 30 ++++++++----------- .../curl_github_packages_spec.rb | 28 ++++++++++++++++- .../download_strategies/curl_post_spec.rb | 19 ++++++++++++ .../test/download_strategies/curl_spec.rb | 30 +++++++++++-------- Library/Homebrew/utils/curl.rb | 26 ++++++++++++++-- 5 files changed, 100 insertions(+), 33 deletions(-) diff --git a/Library/Homebrew/download_strategy.rb b/Library/Homebrew/download_strategy.rb index 0074b62ec7..cd57614bd1 100644 --- a/Library/Homebrew/download_strategy.rb +++ b/Library/Homebrew/download_strategy.rb @@ -463,15 +463,10 @@ class CurlDownloadStrategy < AbstractFileDownloadStrategy url = url.sub(%r{^https?://#{GitHubPackages::URL_DOMAIN}/}o, "#{domain.chomp("/")}/") end - output, _, _status = curl_output( - "--location", "--silent", "--head", "--request", "GET", url.to_s, - timeout: timeout - ) - parsed_output = parse_curl_output(output) + parsed_output = curl_head(url.to_s, timeout: timeout) + parsed_headers = parsed_output.fetch(:responses).map { |r| r.fetch(:headers) } - lines = output.to_s.lines.map(&:chomp) - - final_url = curl_response_follow_redirections(parsed_output[:responses], url) + final_url = curl_response_follow_redirections(parsed_output.fetch(:responses), url) content_disposition_parser = Mechanize::HTTP::ContentDispositionParser.new @@ -500,19 +495,20 @@ class CurlDownloadStrategy < AbstractFileDownloadStrategy File.basename(filename) end - filenames = lines.map(&parse_content_disposition).compact + filenames = parsed_headers.flat_map do |headers| + next [] unless (header = headers["content-disposition"]) - time = - lines.map { |line| line[/^Last-Modified:\s*(.+)/i, 1] } - .compact + [*parse_content_disposition.call("Content-Disposition: #{header}")] + end + + time = parsed_headers + .flat_map { |headers| [*headers["last-modified"]] } .map { |t| t.match?(/^\d+$/) ? Time.at(t.to_i) : Time.parse(t) } .last - file_size = - lines.map { |line| line[/^Content-Length:\s*(\d+)/i, 1] } - .compact - .map(&:to_i) - .last + file_size = parsed_headers + .flat_map { |headers| [*headers["content-length"]&.to_i] } + .last is_redirection = url != final_url basename = filenames.last || parse_basename(final_url, search_query: !is_redirection) diff --git a/Library/Homebrew/test/download_strategies/curl_github_packages_spec.rb b/Library/Homebrew/test/download_strategies/curl_github_packages_spec.rb index 60e19b9db4..1cda9b052b 100644 --- a/Library/Homebrew/test/download_strategies/curl_github_packages_spec.rb +++ b/Library/Homebrew/test/download_strategies/curl_github_packages_spec.rb @@ -9,12 +9,38 @@ describe CurlGitHubPackagesDownloadStrategy do let(:name) { "foo" } let(:url) { "https://#{GitHubPackages::URL_DOMAIN}/v2/homebrew/core/spec_test/manifests/1.2.3" } let(:version) { "1.2.3" } - let(:specs) { {} } + let(:specs) { { headers: ["Accept: application/vnd.oci.image.index.v1+json"] } } let(:authorization) { nil } + let(:head_response) do + <<~HTTP + HTTP/2 200\r + content-length: 12671\r + content-type: application/vnd.oci.image.index.v1+json\r + docker-content-digest: sha256:7d752ee92d9120e3884b452dce15328536a60d468023ea8e9f4b09839a5442e5\r + docker-distribution-api-version: registry/2.0\r + etag: "sha256:7d752ee92d9120e3884b452dce15328536a60d468023ea8e9f4b09839a5442e5"\r + date: Sun, 02 Apr 2023 22:45:08 GMT\r + x-github-request-id: 8814:FA5A:14DAFB5:158D7A2:642A0574\r + HTTP + end describe "#fetch" do before do stub_const("HOMEBREW_GITHUB_PACKAGES_AUTH", authorization) if authorization.present? + + allow(strategy).to receive(:system_command) + .with( + /curl/, + hash_including(args: array_including("--head")), + ) + .twice + .and_return(instance_double( + SystemCommand::Result, + success?: true, + exit_status: instance_double(Process::Status, exitstatus: 0), + stdout: head_response, + )) + strategy.temporary_path.dirname.mkpath FileUtils.touch strategy.temporary_path end diff --git a/Library/Homebrew/test/download_strategies/curl_post_spec.rb b/Library/Homebrew/test/download_strategies/curl_post_spec.rb index c9e7983f26..cdb73bf917 100644 --- a/Library/Homebrew/test/download_strategies/curl_post_spec.rb +++ b/Library/Homebrew/test/download_strategies/curl_post_spec.rb @@ -10,9 +10,28 @@ describe CurlPostDownloadStrategy do let(:url) { "https://example.com/foo.tar.gz" } let(:version) { "1.2.3" } let(:specs) { {} } + let(:head_response) do + <<~HTTP + HTTP/1.1 200\r + Content-Disposition: attachment; filename="foo.tar.gz" + HTTP + end describe "#fetch" do before do + allow(strategy).to receive(:system_command) + .with( + /curl/, + hash_including(args: array_including("--head")), + ) + .twice + .and_return(instance_double( + SystemCommand::Result, + success?: true, + exit_status: instance_double(Process::Status, exitstatus: 0), + stdout: head_response, + )) + strategy.temporary_path.dirname.mkpath FileUtils.touch strategy.temporary_path end diff --git a/Library/Homebrew/test/download_strategies/curl_spec.rb b/Library/Homebrew/test/download_strategies/curl_spec.rb index bd66ae2978..1739ebe7f9 100644 --- a/Library/Homebrew/test/download_strategies/curl_spec.rb +++ b/Library/Homebrew/test/download_strategies/curl_spec.rb @@ -12,6 +12,10 @@ describe CurlDownloadStrategy do let(:specs) { { user: "download:123456" } } let(:artifact_domain) { nil } + before do + allow(strategy).to receive(:curl_head).and_return({ responses: [{ headers: {} }] }) + end + it "parses the opts and sets the corresponding args" do expect(strategy.send(:_curl_args)).to eq(["--user", "download:123456"]) end @@ -190,48 +194,48 @@ describe CurlDownloadStrategy do end describe "#cached_location" do - subject(:cached_location) { described_class.new(url, name, version, **specs).cached_location } + subject(:cached_location) { strategy.cached_location } context "when URL ends with file" do - it { + it "falls back to the file name in the URL" do expect(cached_location).to eq( HOMEBREW_CACHE/"downloads/3d1c0ae7da22be9d83fb1eb774df96b7c4da71d3cf07e1cb28555cf9a5e5af70--foo.tar.gz", ) - } + end end context "when URL file is in middle" do let(:url) { "https://example.com/foo.tar.gz/from/this/mirror" } - it { + it "falls back to the file name in the URL" do expect(cached_location).to eq( HOMEBREW_CACHE/"downloads/1ab61269ba52c83994510b1e28dd04167a2f2e8393a35a9c50c1f7d33fd8f619--foo.tar.gz", ) - } + end end context "with a file name trailing the URL path" do let(:url) { "https://example.com/cask.dmg" } - it { + it "falls back to the file extension in the URL" do expect(cached_location.extname).to eq(".dmg") - } + end end context "with a file name trailing the first query parameter" do let(:url) { "https://example.com/download?file=cask.zip&a=1" } - it { + it "falls back to the file extension in the URL" do expect(cached_location.extname).to eq(".zip") - } + end end context "with a file name trailing the second query parameter" do let(:url) { "https://example.com/dl?a=1&file=cask.zip&b=2" } - it { + it "falls back to the file extension in the URL" do expect(cached_location.extname).to eq(".zip") - } + end end context "with an unusually long query string" do @@ -253,10 +257,10 @@ describe CurlDownloadStrategy do ].join end - it { + it "falls back to the file extension in the URL" do expect(cached_location.extname).to eq(".zip") expect(cached_location.to_path.length).to be_between(0, 255) - } + end end end end diff --git a/Library/Homebrew/utils/curl.rb b/Library/Homebrew/utils/curl.rb index 7c89caae16..2687ad268d 100644 --- a/Library/Homebrew/utils/curl.rb +++ b/Library/Homebrew/utils/curl.rb @@ -141,7 +141,7 @@ module Utils raise Timeout::Error, result.stderr.lines.last.chomp if timeout && result.status.exitstatus == 28 # Error in the HTTP2 framing layer - if result.status.exitstatus == 16 + if result.exit_status == 16 return curl_with_workarounds( *args, "--http1.1", timeout: end_time&.remaining, **command_options, **options @@ -149,7 +149,7 @@ module Utils end # This is a workaround for https://github.com/curl/curl/issues/1618. - if result.status.exitstatus == 56 # Unexpected EOF + if result.exit_status == 56 # Unexpected EOF out = curl_output("-V").stdout # If `curl` doesn't support HTTP2, the exception is unrelated to this bug. @@ -207,6 +207,28 @@ module Utils curl_with_workarounds(*args, print_stderr: false, show_output: true, **options) end + def curl_head(*args, **options) + [[], ["--request", "GET"]].each do |request_args| + result = curl_output( + "--fail", "--location", "--silent", "--head", *request_args, *args, + **options + ) + + # 22 means a non-successful HTTP status code, not a `curl` error, so we still got some headers. + if result.success? || result.exit_status == 22 + parsed_output = parse_curl_output(result.stdout) + + # If we didn't get a `Content-Disposition` header yet, retry using `GET`. + next if request_args.empty? && + parsed_output.fetch(:responses).none? { |r| r.fetch(:headers).key?("content-disposition") } + + return parsed_output if result.success? + end + + result.assert_success! + end + end + # Check if a URL is protected by CloudFlare (e.g. badlion.net and jaxx.io). # @param response [Hash] A response hash from `#parse_curl_response`. # @return [true, false] Whether a response contains headers indicating that From 93de196a345c88acc67b2ab4c1243ade9774b45b Mon Sep 17 00:00:00 2001 From: Issy Long Date: Thu, 6 Apr 2023 09:49:20 +0100 Subject: [PATCH 26/28] Update Library/Homebrew/cask/audit.rb --- Library/Homebrew/cask/audit.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/cask/audit.rb b/Library/Homebrew/cask/audit.rb index b6597bf36b..0b9c12188a 100644 --- a/Library/Homebrew/cask/audit.rb +++ b/Library/Homebrew/cask/audit.rb @@ -643,7 +643,8 @@ module Cask return if metadata.nil? return unless metadata["archived"] - add_error("GitHub repo is archived", strict_only: cask.discontinued?) + # Discontinued casks shouldn't show up as errors. + add_error("GitHub repo is archived", strict_only: !cask.discontinued?) end sig { void } From a1d4a46f064bbf0957ed797a094d3ab774406013 Mon Sep 17 00:00:00 2001 From: Issy Long Date: Thu, 6 Apr 2023 10:13:02 +0100 Subject: [PATCH 27/28] Update Library/Homebrew/cask/audit.rb Co-authored-by: Markus Reiter --- Library/Homebrew/cask/audit.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/cask/audit.rb b/Library/Homebrew/cask/audit.rb index 0b9c12188a..34f0ffb9c9 100644 --- a/Library/Homebrew/cask/audit.rb +++ b/Library/Homebrew/cask/audit.rb @@ -658,7 +658,8 @@ module Cask return if metadata.nil? return unless metadata["archived"] - add_error("GitLab repo is archived", strict_only: cask.discontinued?) + # Discontinued casks shouldn't show up as errors. + add_error("GitLab repo is archived") unless cask.discontinued? end sig { void } From 8319c8f9b936cffa43571571e6eaf2f266f8e3df Mon Sep 17 00:00:00 2001 From: Issy Long Date: Thu, 6 Apr 2023 21:24:27 +0100 Subject: [PATCH 28/28] Make `audit_casks` return `[path, { errors:, warnings:}]` for CI - This was failing but only in CI because the annotations require "errors" and "warnings" hash elements. Since formulae have this despite formulae not having warnings (probably for compatibility with casks), I decided to reinstate `errors` and `warnings` hash for Casks _right at the end_ and we can clean this up another time (famous last words). --- Library/Homebrew/cask/cmd/audit.rb | 4 ++-- Library/Homebrew/dev-cmd/audit.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Library/Homebrew/cask/cmd/audit.rb b/Library/Homebrew/cask/cmd/audit.rb index 57ba90e369..363c779ec1 100644 --- a/Library/Homebrew/cask/cmd/audit.rb +++ b/Library/Homebrew/cask/cmd/audit.rb @@ -60,7 +60,7 @@ module Cask except: [], ) - failed_casks = results.reject { |_, result| result.empty? }.map(&:first) + failed_casks = results.reject { |_, result| result[:errors].empty? }.map(&:first) return if failed_casks.empty? raise CaskError, "audit failed for casks: #{failed_casks.join(" ")}" @@ -102,7 +102,7 @@ module Cask casks.to_h do |cask| odebug "Auditing Cask #{cask}" - [cask.sourcefile_path, Auditor.audit(cask, **options)] + [cask.sourcefile_path, { errors: Auditor.audit(cask, **options), warnings: [] }] end end end diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index bd919b84bb..db4a084d25 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -266,7 +266,7 @@ module Homebrew ) end - failed_casks = cask_results.reject { |_, result| result.empty? } + failed_casks = cask_results.reject { |_, result| result[:errors].empty? } cask_count = failed_casks.count