From c8299edb39eecb4bab7e55746ef69156ffea9a86 Mon Sep 17 00:00:00 2001 From: BrewTestBot <1589480+BrewTestBot@users.noreply.github.com> Date: Thu, 1 Apr 2021 00:24:16 +0000 Subject: [PATCH 01/11] sorbet: Update RBI files. Autogenerated by the [sorbet](https://github.com/Homebrew/brew/blob/master/.github/workflows/sorbet.yml) workflow. --- Library/Homebrew/sorbet/rbi/hidden-definitions/hidden.rbi | 1 + 1 file changed, 1 insertion(+) diff --git a/Library/Homebrew/sorbet/rbi/hidden-definitions/hidden.rbi b/Library/Homebrew/sorbet/rbi/hidden-definitions/hidden.rbi index 49fc0b4664..19a7bcc1f0 100644 --- a/Library/Homebrew/sorbet/rbi/hidden-definitions/hidden.rbi +++ b/Library/Homebrew/sorbet/rbi/hidden-definitions/hidden.rbi @@ -12603,6 +12603,7 @@ class Object DEPRECATED_OFFICIAL_TAPS = ::T.let(nil, ::T.untyped) ENV = ::T.let(nil, ::T.untyped) FORMULA_COMPONENT_PRECEDENCE_LIST = ::T.let(nil, ::T.untyped) + HOMEBREW_BOTTLES_EXTNAME_REGEX = ::T.let(nil, ::T.untyped) HOMEBREW_BOTTLE_DEFAULT_DOMAIN = ::T.let(nil, ::T.untyped) HOMEBREW_BREW_DEFAULT_GIT_REMOTE = ::T.let(nil, ::T.untyped) HOMEBREW_BREW_FILE = ::T.let(nil, ::T.untyped) From 6e2adcc461a61462f80eeb2148bfce1ae49d0ddb Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Wed, 31 Mar 2021 20:38:53 +0100 Subject: [PATCH 02/11] github_packages: update mediaType. This custom type will allow better display in GitHub Packages. --- Library/Homebrew/github_packages.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/github_packages.rb b/Library/Homebrew/github_packages.rb index f16f076d77..f3d628a34a 100644 --- a/Library/Homebrew/github_packages.rb +++ b/Library/Homebrew/github_packages.rb @@ -220,12 +220,12 @@ class GitHubPackages image_manifest = { schemaVersion: 2, config: { - mediaType: "application/vnd.oci.image.config.v1+json", + mediaType: "application/vnd.homebrew.formula.config.v1+json", digest: "sha256:#{config_json_sha256}", size: config_json_size, }, layers: [{ - mediaType: "application/vnd.oci.image.layer.v1.tar+gzip", + mediaType: "application/vnd.homebrew.bottle.layer.v1.tar+gzip", digest: "sha256:#{tar_gz_sha256}", size: File.size(local_file), annotations: { From 7314ad55b4260280a796cc9d3b2da7ad0f4bc884 Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Thu, 1 Apr 2021 13:25:30 +0100 Subject: [PATCH 03/11] workflows/tests: remove cask taps audit. These are just too error-prone. They shouldn't be re-enabled until our CI is setup such that it's impossible for any changes to be merged into homebrew-cask if these are failing. --- .github/workflows/tests.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d9cf932fb6..fdd73ceb61 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -275,12 +275,6 @@ jobs: - name: Run brew readall on all taps run: brew readall --aliases - - name: Run brew audit --skip-style on Cask taps - run: | - brew audit --skip-style --display-failures-only --tap=homebrew/cask - brew audit --skip-style --display-failures-only --tap=homebrew/cask-drivers - brew audit --skip-style --display-failures-only --tap=homebrew/cask-fonts - - name: Install brew tests dependencies run: | brew install subversion From 59dae75709bb27c704ec7834779aa8c0f045d5b2 Mon Sep 17 00:00:00 2001 From: nandahkrishna Date: Thu, 1 Apr 2021 16:23:39 +0530 Subject: [PATCH 04/11] Allow specifying committer for some `dev-cmd`s --- Library/Homebrew/dev-cmd/bottle.rb | 10 +++++++++- Library/Homebrew/dev-cmd/pr-pull.rb | 10 +++++++++- Library/Homebrew/dev-cmd/pr-upload.rb | 3 +++ Library/Homebrew/test/utils_spec.rb | 13 +++++++++++++ Library/Homebrew/utils.rb | 7 +++++++ 5 files changed, 41 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/dev-cmd/bottle.rb b/Library/Homebrew/dev-cmd/bottle.rb index 2a9759adeb..3924598f05 100644 --- a/Library/Homebrew/dev-cmd/bottle.rb +++ b/Library/Homebrew/dev-cmd/bottle.rb @@ -73,6 +73,8 @@ module Homebrew switch "--only-json-tab", depends_on: "--json", description: "When passed with `--json`, the tab will be written to the JSON file but not the bottle." + flag "--committer=", + description: "Specify a committer name and email in `git`'s standard author format." flag "--root-url=", description: "Use the specified as the root of the bottle's URL instead of Homebrew's default." @@ -619,9 +621,15 @@ module Homebrew path.atomic_write(formula_ast.process) unless args.no_commit? - Utils::Git.set_name_email! + Utils::Git.set_name_email!(committer: args.committer.blank?) Utils::Git.setup_gpg! + if (committer = args.committer) + committer = Utils.parse_author!(committer) + ENV["GIT_COMMITTER_NAME"] = committer[:name] + ENV["GIT_COMMITTER_EMAIL"] = committer[:email] + end + short_name = formula_name.split("/", -1).last pkg_version = bottle_hash["formula"]["pkg_version"] diff --git a/Library/Homebrew/dev-cmd/pr-pull.rb b/Library/Homebrew/dev-cmd/pr-pull.rb index fb4e67d4cc..201b108a59 100644 --- a/Library/Homebrew/dev-cmd/pr-pull.rb +++ b/Library/Homebrew/dev-cmd/pr-pull.rb @@ -44,6 +44,8 @@ module Homebrew switch "--warn-on-upload-failure", description: "Warn instead of raising an error if the bottle upload fails. "\ "Useful for repairing bottle uploads that previously failed." + flag "--committer=", + description: "Specify a committer name and email in `git`'s standard author format." flag "--message=", depends_on: "--autosquash", description: "Message to include when autosquashing revision bumps, deletions, and rebuilds." @@ -365,9 +367,15 @@ module Homebrew mirror_repo = args.bintray_mirror || "mirror" tap = Tap.fetch(args.tap || CoreTap.instance.name) - Utils::Git.set_name_email! + Utils::Git.set_name_email!(committer: args.committer.blank?) Utils::Git.setup_gpg! + if (committer = args.committer) + committer = Utils.parse_author!(committer) + ENV["GIT_COMMITTER_NAME"] = committer[:name] + ENV["GIT_COMMITTER_EMAIL"] = committer[:email] + end + args.named.uniq.each do |arg| arg = "#{tap.default_remote}/pull/#{arg}" if arg.to_i.positive? url_match = arg.match HOMEBREW_PULL_OR_COMMIT_URL_REGEX diff --git a/Library/Homebrew/dev-cmd/pr-upload.rb b/Library/Homebrew/dev-cmd/pr-upload.rb index e0d7e91e9c..fedb8eace6 100644 --- a/Library/Homebrew/dev-cmd/pr-upload.rb +++ b/Library/Homebrew/dev-cmd/pr-upload.rb @@ -30,6 +30,8 @@ module Homebrew switch "--warn-on-upload-failure", description: "Warn instead of raising an error if the bottle upload fails. "\ "Useful for repairing bottle uploads that previously failed." + flag "--committer=", + description: "Specify a committer name and email in `git`'s standard author format." flag "--archive-item=", description: "Upload to the specified Internet Archive item (default: `homebrew`)." flag "--bintray-org=", @@ -103,6 +105,7 @@ module Homebrew bottle_args << "--debug" if args.debug? bottle_args << "--keep-old" if args.keep_old? bottle_args << "--root-url=#{args.root_url}" if args.root_url + bottle_args << "--committer='#{args.committer}'" if args.committer bottle_args << "--no-commit" if args.no_commit? bottle_args += json_files diff --git a/Library/Homebrew/test/utils_spec.rb b/Library/Homebrew/test/utils_spec.rb index 380b1d3803..c54a886574 100644 --- a/Library/Homebrew/test/utils_spec.rb +++ b/Library/Homebrew/test/utils_spec.rb @@ -210,6 +210,19 @@ describe "globally-scoped helper methods" do end end + specify "#parse_author!" do + parse_error_msg = /Unable to parse name and email/ + + expect(parse_author!("John Doe ")) + .to eq({ name: "John Doe", email: "john.doe@example.com" }) + expect { parse_author!("") } + .to raise_error(parse_error_msg) + expect { parse_author!("John Doe") } + .to raise_error(parse_error_msg) + expect { parse_author!("") } + .to raise_error(parse_error_msg) + end + specify "#disk_usage_readable" do expect(disk_usage_readable(1)).to eq("1B") expect(disk_usage_readable(1000)).to eq("1000B") diff --git a/Library/Homebrew/utils.rb b/Library/Homebrew/utils.rb index 01fee6c88a..0888e7f046 100644 --- a/Library/Homebrew/utils.rb +++ b/Library/Homebrew/utils.rb @@ -467,6 +467,13 @@ module Kernel end.uniq.compact end + def parse_author!(author) + /^(?[^<]+?)[ \t]*<(?[^>]+?)>$/ =~ author + raise "Unable to parse name and email." if name.blank? && email.blank? + + { name: name, email: email } + end + def disk_usage_readable(size_in_bytes) if size_in_bytes >= 1_073_741_824 size = size_in_bytes.to_f / 1_073_741_824 From f812654cc18671cf823a6267808281300d55c09a Mon Sep 17 00:00:00 2001 From: nandahkrishna Date: Thu, 1 Apr 2021 22:21:30 +0530 Subject: [PATCH 05/11] utils: raise `UsageError` in `parse_author!` Co-authored-by: Mike McQuaid --- Library/Homebrew/utils.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/utils.rb b/Library/Homebrew/utils.rb index 0888e7f046..cc1bf9c445 100644 --- a/Library/Homebrew/utils.rb +++ b/Library/Homebrew/utils.rb @@ -469,7 +469,7 @@ module Kernel def parse_author!(author) /^(?[^<]+?)[ \t]*<(?[^>]+?)>$/ =~ author - raise "Unable to parse name and email." if name.blank? && email.blank? + raise UsageError, "Unable to parse name and email." if name.blank? && email.blank? { name: name, email: email } end From 731b4fce5b177528e2b2a6a1a3b894c249a53035 Mon Sep 17 00:00:00 2001 From: BrewTestBot <1589480+BrewTestBot@users.noreply.github.com> Date: Thu, 1 Apr 2021 17:14:57 +0000 Subject: [PATCH 06/11] Update maintainers, manpage and completions. Autogenerated by the [update-manpage](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/update-manpage.yml) workflow. --- completions/bash/brew | 3 +++ completions/fish/brew.fish | 3 +++ completions/zsh/_brew | 3 +++ docs/Manpage.md | 6 ++++++ manpages/brew.1 | 12 ++++++++++++ 5 files changed, 27 insertions(+) diff --git a/completions/bash/brew b/completions/bash/brew index 93f5aa2320..58eed9bd5a 100644 --- a/completions/bash/brew +++ b/completions/bash/brew @@ -372,6 +372,7 @@ _brew_bottle() { case "$cur" in -*) __brewcomp " + --committer --debug --force-core-tap --help @@ -1456,6 +1457,7 @@ _brew_pr_pull() { --bintray-org --branch-okay --clean + --committer --debug --dry-run --help @@ -1484,6 +1486,7 @@ _brew_pr_upload() { __brewcomp " --archive-item --bintray-org + --committer --debug --dry-run --github-org diff --git a/completions/fish/brew.fish b/completions/fish/brew.fish index 5e8745ea2b..35e18589f0 100644 --- a/completions/fish/brew.fish +++ b/completions/fish/brew.fish @@ -357,6 +357,7 @@ __fish_brew_complete_arg 'autoremove' -l verbose -d 'Make some output more verbo __fish_brew_complete_cmd 'bottle' 'Generate a bottle (binary package) from a formula that was installed with `--build-bottle`' +__fish_brew_complete_arg 'bottle' -l committer -d 'Specify a committer name and email in `git`\'s standard author format' __fish_brew_complete_arg 'bottle' -l debug -d 'Display any debugging information' __fish_brew_complete_arg 'bottle' -l force-core-tap -d 'Build a bottle even if formula is not in `homebrew/core` or any installed taps' __fish_brew_complete_arg 'bottle' -l help -d 'Show this message' @@ -1050,6 +1051,7 @@ __fish_brew_complete_arg 'pr-pull' -l bintray-mirror -d 'Use the specified Bintr __fish_brew_complete_arg 'pr-pull' -l bintray-org -d 'Upload to the specified Bintray organisation (default: `homebrew`)' __fish_brew_complete_arg 'pr-pull' -l branch-okay -d 'Do not warn if pulling to a branch besides the repository default (useful for testing)' __fish_brew_complete_arg 'pr-pull' -l clean -d 'Do not amend the commits from pull requests' +__fish_brew_complete_arg 'pr-pull' -l committer -d 'Specify a committer name and email in `git`\'s standard author format' __fish_brew_complete_arg 'pr-pull' -l debug -d 'Display any debugging information' __fish_brew_complete_arg 'pr-pull' -l dry-run -d 'Print what would be done rather than doing it' __fish_brew_complete_arg 'pr-pull' -l help -d 'Show this message' @@ -1070,6 +1072,7 @@ __fish_brew_complete_arg 'pr-pull' -l workflows -d 'Retrieve artifacts from the __fish_brew_complete_cmd 'pr-upload' 'Apply the bottle commit and publish bottles to a host' __fish_brew_complete_arg 'pr-upload' -l archive-item -d 'Upload to the specified Internet Archive item (default: `homebrew`)' __fish_brew_complete_arg 'pr-upload' -l bintray-org -d 'Upload to the specified Bintray organisation (default: `homebrew`)' +__fish_brew_complete_arg 'pr-upload' -l committer -d 'Specify a committer name and email in `git`\'s standard author format' __fish_brew_complete_arg 'pr-upload' -l debug -d 'Display any debugging information' __fish_brew_complete_arg 'pr-upload' -l dry-run -d 'Print what would be done rather than doing it' __fish_brew_complete_arg 'pr-upload' -l github-org -d 'Upload to the specified GitHub organisation\'s GitHub Packages (default: `homebrew`)' diff --git a/completions/zsh/_brew b/completions/zsh/_brew index bd3416ee97..75822a7bf9 100644 --- a/completions/zsh/_brew +++ b/completions/zsh/_brew @@ -445,6 +445,7 @@ _brew_autoremove() { # brew bottle _brew_bottle() { _arguments \ + '--committer[Specify a committer name and email in `git`'\''s standard author format]' \ '--debug[Display any debugging information]' \ '--force-core-tap[Build a bottle even if formula is not in `homebrew/core` or any installed taps]' \ '--help[Show this message]' \ @@ -1293,6 +1294,7 @@ _brew_pr_pull() { '(--archive-item)--bintray-org[Upload to the specified Bintray organisation (default: `homebrew`)]' \ '--branch-okay[Do not warn if pulling to a branch besides the repository default (useful for testing)]' \ '(--autosquash)--clean[Do not amend the commits from pull requests]' \ + '--committer[Specify a committer name and email in `git`'\''s standard author format]' \ '--debug[Display any debugging information]' \ '--dry-run[Print what would be done rather than doing it]' \ '--help[Show this message]' \ @@ -1315,6 +1317,7 @@ _brew_pr_upload() { _arguments \ '--archive-item[Upload to the specified Internet Archive item (default: `homebrew`)]' \ '--bintray-org[Upload to the specified Bintray organisation (default: `homebrew`)]' \ + '--committer[Specify a committer name and email in `git`'\''s standard author format]' \ '--debug[Display any debugging information]' \ '--dry-run[Print what would be done rather than doing it]' \ '--github-org[Upload to the specified GitHub organisation'\''s GitHub Packages (default: `homebrew`)]' \ diff --git a/docs/Manpage.md b/docs/Manpage.md index f584b03dc6..5f219589c2 100644 --- a/docs/Manpage.md +++ b/docs/Manpage.md @@ -825,6 +825,8 @@ value, while `--no-rebuild` will remove it. When passed with `--write`, a new commit will not generated after writing changes to the formula file. * `--only-json-tab`: When passed with `--json`, the tab will be written to the JSON file but not the bottle. +* `--committer`: + Specify a committer name and email in `git`'s standard author format. * `--root-url`: Use the specified *`URL`* as the root of the bottle's URL instead of Homebrew's default. @@ -1183,6 +1185,8 @@ Requires write access to the repository. When a patch fails to apply, leave in progress and allow user to resolve, instead of aborting. * `--warn-on-upload-failure`: Warn instead of raising an error if the bottle upload fails. Useful for repairing bottle uploads that previously failed. +* `--committer`: + Specify a committer name and email in `git`'s standard author format. * `--message`: Message to include when autosquashing revision bumps, deletions, and rebuilds. * `--artifact`: @@ -1216,6 +1220,8 @@ Apply the bottle commit and publish bottles to a host. Do not generate a new commit before uploading. * `--warn-on-upload-failure`: Warn instead of raising an error if the bottle upload fails. Useful for repairing bottle uploads that previously failed. +* `--committer`: + Specify a committer name and email in `git`'s standard author format. * `--archive-item`: Upload to the specified Internet Archive item (default: `homebrew`). * `--bintray-org`: diff --git a/manpages/brew.1 b/manpages/brew.1 index c90c0dd49d..1d55a3c820 100644 --- a/manpages/brew.1 +++ b/manpages/brew.1 @@ -1137,6 +1137,10 @@ When passed with \fB\-\-write\fR, a new commit will not generated after writing When passed with \fB\-\-json\fR, the tab will be written to the JSON file but not the bottle\. . .TP +\fB\-\-committer\fR +Specify a committer name and email in \fBgit\fR\'s standard author format\. +. +.TP \fB\-\-root\-url\fR Use the specified \fIURL\fR as the root of the bottle\'s URL instead of Homebrew\'s default\. . @@ -1653,6 +1657,10 @@ When a patch fails to apply, leave in progress and allow user to resolve, instea Warn instead of raising an error if the bottle upload fails\. Useful for repairing bottle uploads that previously failed\. . .TP +\fB\-\-committer\fR +Specify a committer name and email in \fBgit\fR\'s standard author format\. +. +.TP \fB\-\-message\fR Message to include when autosquashing revision bumps, deletions, and rebuilds\. . @@ -1712,6 +1720,10 @@ Do not generate a new commit before uploading\. Warn instead of raising an error if the bottle upload fails\. Useful for repairing bottle uploads that previously failed\. . .TP +\fB\-\-committer\fR +Specify a committer name and email in \fBgit\fR\'s standard author format\. +. +.TP \fB\-\-archive\-item\fR Upload to the specified Internet Archive item (default: \fBhomebrew\fR)\. . From 93ccf1ef6a92fbca61f45f3ea1e20a851f3748e4 Mon Sep 17 00:00:00 2001 From: Dawid Dziurla Date: Thu, 1 Apr 2021 23:46:44 +0200 Subject: [PATCH 07/11] pr-pull: pass --committer to pr-upload --- Library/Homebrew/dev-cmd/pr-pull.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/Library/Homebrew/dev-cmd/pr-pull.rb b/Library/Homebrew/dev-cmd/pr-pull.rb index 201b108a59..c32e77520b 100644 --- a/Library/Homebrew/dev-cmd/pr-pull.rb +++ b/Library/Homebrew/dev-cmd/pr-pull.rb @@ -435,6 +435,7 @@ module Homebrew upload_args << "--dry-run" if args.dry_run? upload_args << "--keep-old" if args.keep_old? upload_args << "--warn-on-upload-failure" if args.warn_on_upload_failure? + upload_args << "--committer='#{args.committer}'" if args.committer upload_args << "--root-url=#{args.root_url}" if args.root_url upload_args << if archive_item.present? "--archive-item=#{archive_item}" From 64c53f1a370fa99b78f8f1ef97c67209024e1fac Mon Sep 17 00:00:00 2001 From: Dawid Dziurla Date: Fri, 2 Apr 2021 00:17:43 +0200 Subject: [PATCH 08/11] pr-pull,upload: don't quote passed --committer value --- Library/Homebrew/dev-cmd/pr-pull.rb | 2 +- Library/Homebrew/dev-cmd/pr-upload.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/dev-cmd/pr-pull.rb b/Library/Homebrew/dev-cmd/pr-pull.rb index c32e77520b..345cc2c885 100644 --- a/Library/Homebrew/dev-cmd/pr-pull.rb +++ b/Library/Homebrew/dev-cmd/pr-pull.rb @@ -435,7 +435,7 @@ module Homebrew upload_args << "--dry-run" if args.dry_run? upload_args << "--keep-old" if args.keep_old? upload_args << "--warn-on-upload-failure" if args.warn_on_upload_failure? - upload_args << "--committer='#{args.committer}'" if args.committer + upload_args << "--committer=#{args.committer}" if args.committer upload_args << "--root-url=#{args.root_url}" if args.root_url upload_args << if archive_item.present? "--archive-item=#{archive_item}" diff --git a/Library/Homebrew/dev-cmd/pr-upload.rb b/Library/Homebrew/dev-cmd/pr-upload.rb index fedb8eace6..3a38754079 100644 --- a/Library/Homebrew/dev-cmd/pr-upload.rb +++ b/Library/Homebrew/dev-cmd/pr-upload.rb @@ -105,7 +105,7 @@ module Homebrew bottle_args << "--debug" if args.debug? bottle_args << "--keep-old" if args.keep_old? bottle_args << "--root-url=#{args.root_url}" if args.root_url - bottle_args << "--committer='#{args.committer}'" if args.committer + bottle_args << "--committer=#{args.committer}" if args.committer bottle_args << "--no-commit" if args.no_commit? bottle_args += json_files From b843ca881c41a07f59283780ce0149005ae811aa Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Wed, 31 Mar 2021 06:14:41 +0200 Subject: [PATCH 09/11] Implement nested `url do` API. --- Library/Homebrew/cask/dsl.rb | 34 ++++-- Library/Homebrew/cask/url.rb | 209 ++++++++++++++++++++++++++++------ Library/Homebrew/cask/url.rbi | 6 + 3 files changed, 205 insertions(+), 44 deletions(-) create mode 100644 Library/Homebrew/cask/url.rbi diff --git a/Library/Homebrew/cask/dsl.rb b/Library/Homebrew/cask/dsl.rb index a46a7c18bc..d7648987a0 100644 --- a/Library/Homebrew/cask/dsl.rb +++ b/Library/Homebrew/cask/dsl.rb @@ -96,6 +96,7 @@ module Cask @token = cask.token end + # @api public def name(*args) @name ||= [] return @name if args.empty? @@ -103,6 +104,7 @@ module Cask @name.concat(args.flatten) end + # @api public def desc(description = nil) set_unique_stanza(:desc, description.nil?) { description } end @@ -121,6 +123,7 @@ module Cask raise CaskInvalidError.new(cask, "'#{stanza}' stanza failed with: #{e}") end + # @api public def homepage(homepage = nil) set_unique_stanza(:homepage, homepage.nil?) { homepage } end @@ -176,32 +179,32 @@ module Cask @language_blocks.keys.flatten end - def url(*args, **options) + # @api public + def url(*args, **options, &block) caller_location = caller_locations[0] - set_unique_stanza(:url, args.empty? && options.empty? && !block_given?) do - if block_given? - LazyObject.new do - *args = yield - options = args.last.is_a?(Hash) ? args.pop : {} - URL.new(*args, **options, from_block: true, caller_location: caller_location) - end + set_unique_stanza(:url, args.empty? && options.empty? && !block) do + if block + URL.new(*args, **options, caller_location: caller_location, dsl: self, &block) else URL.new(*args, **options, caller_location: caller_location) end end end + # @api public def appcast(*args) set_unique_stanza(:appcast, args.empty?) { DSL::Appcast.new(*args) } end + # @api public def container(*args) set_unique_stanza(:container, args.empty?) do DSL::Container.new(*args) end end + # @api public def version(arg = nil) set_unique_stanza(:version, arg.nil?) do if !arg.is_a?(String) && arg != :latest @@ -212,6 +215,7 @@ module Cask end end + # @api public def sha256(arg = nil) set_unique_stanza(:sha256, arg.nil?) do case arg @@ -226,6 +230,7 @@ module Cask end # `depends_on` uses a load method so that multiple stanzas can be merged. + # @api public def depends_on(*args) @depends_on ||= DSL::DependsOn.new return @depends_on if args.empty? @@ -238,6 +243,7 @@ module Cask @depends_on end + # @api public def conflicts_with(*args) # TODO: remove this constraint, and instead merge multiple conflicts_with stanzas set_unique_stanza(:conflicts_with, args.empty?) { DSL::ConflictsWith.new(*args) } @@ -251,6 +257,7 @@ module Cask cask.caskroom_path end + # @api public def staged_path return @staged_path if @staged_path @@ -258,6 +265,7 @@ module Cask @staged_path = caskroom_path.join(cask_version.to_s) end + # @api public def caveats(*strings, &block) @caveats ||= DSL::Caveats.new(cask) if block @@ -276,10 +284,12 @@ module Cask @caveats&.discontinued? end + # @api public def auto_updates(auto_updates = nil) set_unique_stanza(:auto_updates, auto_updates.nil?) { auto_updates } end + # @api public def livecheck(&block) @livecheck ||= Livecheck.new(self) return @livecheck unless block @@ -317,8 +327,6 @@ module Cask end end - # No need to define it as it's the default/superclass implementation. - # rubocop:disable Style/MissingRespondToMissing def method_missing(method, *) if method Utils.method_missing_message(method, token) @@ -327,8 +335,12 @@ module Cask super end end - # rubocop:enable Style/MissingRespondToMissing + def respond_to_missing?(*) + true + end + + # @api public def appdir cask.config.appdir end diff --git a/Library/Homebrew/cask/url.rb b/Library/Homebrew/cask/url.rb index 5819f43606..3d39fbfb7a 100644 --- a/Library/Homebrew/cask/url.rb +++ b/Library/Homebrew/cask/url.rb @@ -4,21 +4,146 @@ # Class corresponding to the `url` stanza. # # @api private -class URL +class URL < Delegator extend T::Sig - attr_reader :uri, :specs, - :verified, :using, - :tag, :branch, :revisions, :revision, - :trust_cert, :cookies, :referer, :header, :user_agent, - :data + # @api private + class DSL + extend T::Sig - extend Forwardable - def_delegators :uri, :path, :scheme, :to_s + attr_reader :uri, :specs, + :verified, :using, + :tag, :branch, :revisions, :revision, + :trust_cert, :cookies, :referer, :header, :user_agent, + :data + + extend Forwardable + def_delegators :uri, :path, :scheme, :to_s + + # @api public + sig { + params( + uri: T.any(URI::Generic, String), + verified: T.nilable(String), + using: T.nilable(Symbol), + tag: T.nilable(String), + branch: T.nilable(String), + revisions: T.nilable(T::Array[String]), + revision: T.nilable(String), + trust_cert: T.nilable(T::Boolean), + cookies: T.nilable(T::Hash[String, String]), + referer: T.nilable(T.any(URI::Generic, String)), + header: T.nilable(String), + user_agent: T.nilable(T.any(Symbol, String)), + data: T.nilable(T::Hash[String, String]), + ).void + } + def initialize( + uri, + verified: nil, + using: nil, + tag: nil, + branch: nil, + revisions: nil, + revision: nil, + trust_cert: nil, + cookies: nil, + referer: nil, + header: nil, + user_agent: nil, + data: nil + ) + + @uri = URI(uri) + + specs = {} + specs[:verified] = @verified = verified + specs[:using] = @using = using + specs[:tag] = @tag = tag + specs[:branch] = @branch = branch + specs[:revisions] = @revisions = revisions + specs[:revision] = @revision = revision + specs[:trust_cert] = @trust_cert = trust_cert + specs[:cookies] = @cookies = cookies + specs[:referer] = @referer = referer + specs[:header] = @header = header + specs[:user_agent] = @user_agent = user_agent || :default + specs[:data] = @data = data + + @specs = specs.compact + end + end + + # @api private + class BlockDSL + extend T::Sig + + module PageWithURL + extend T::Sig + + # @api public + sig { returns(URI::Generic) } + attr_accessor :url + end + + sig { + params( + uri: T.nilable(T.any(URI::Generic, String)), + dsl: T.nilable(Cask::DSL), + block: T.proc.params(arg0: T.all(String, PageWithURL)).returns(T.untyped), + ).void + } + def initialize(uri, dsl: nil, &block) + @uri = uri + @dsl = dsl + @block = block + end + + sig { returns(T.untyped) } + def call + if @uri + result = curl_output("--fail", "--silent", "--location", @uri) + result.assert_success! + + page = result.stdout + page.extend PageWithURL + page.url = URI(@uri) + + instance_exec(page, &@block) + else + instance_exec(&@block) + end + end + + # @api public + sig { + params( + uri: T.any(URI::Generic, String), + block: T.proc.params(arg0: T.all(String, PageWithURL)).returns(T.untyped), + ).void + } + def url(uri, &block) + self.class.new(uri, &block).call + end + private :url + + # @api public + def method_missing(method, *args, **options, &block) + if @dsl.respond_to?(method) + T.unsafe(@dsl).public_send(method, *args, **options, &block) + else + super + end + end + + def respond_to_missing?(method, include_all) + @dsl.respond_to?(method, include_all) || super + end + end sig { params( - uri: T.any(URI::Generic, String), + uri: T.nilable(T.any(URI::Generic, String)), verified: T.nilable(String), using: T.nilable(Symbol), tag: T.nilable(String), @@ -31,12 +156,13 @@ class URL header: T.nilable(String), user_agent: T.nilable(T.any(Symbol, String)), data: T.nilable(T::Hash[String, String]), - from_block: T::Boolean, caller_location: Thread::Backtrace::Location, - ).returns(T.untyped) + dsl: T.nilable(Cask::DSL), + block: T.nilable(T.proc.params(arg0: T.all(String, BlockDSL::PageWithURL)).returns(T.untyped)), + ).void } def initialize( - uri, + uri = nil, verified: nil, using: nil, tag: nil, @@ -49,32 +175,49 @@ class URL header: nil, user_agent: nil, data: nil, - from_block: false, - caller_location: T.must(caller_locations).fetch(0) + caller_location: T.must(caller_locations).fetch(0), + dsl: nil, + &block ) + super( + if block + LazyObject.new do + *args = BlockDSL.new(uri, dsl: dsl, &block).call + options = args.last.is_a?(Hash) ? args.pop : {} + uri = T.let(args.first, T.any(URI::Generic, String)) + DSL.new(uri, **options) + end + else + DSL.new( + T.must(uri), + verified: verified, + using: using, + tag: tag, + branch: branch, + revisions: revisions, + revision: revision, + trust_cert: trust_cert, + cookies: cookies, + referer: referer, + header: header, + user_agent: user_agent, + data: data, + ) + end + ) - @uri = URI(uri) - - specs = {} - specs[:verified] = @verified = verified - specs[:using] = @using = using - specs[:tag] = @tag = tag - specs[:branch] = @branch = branch - specs[:revisions] = @revisions = revisions - specs[:revision] = @revision = revision - specs[:trust_cert] = @trust_cert = trust_cert - specs[:cookies] = @cookies = cookies - specs[:referer] = @referer = referer - specs[:header] = @header = header - specs[:user_agent] = @user_agent = user_agent || :default - specs[:data] = @data = data - - @specs = specs.compact - - @from_block = from_block + @from_block = !block.nil? @caller_location = caller_location end + def __getobj__ + @dsl + end + + def __setobj__(dsl) + @dsl = dsl + end + sig { returns(T.nilable(String)) } def raw_interpolated_url return @raw_interpolated_url if defined?(@raw_interpolated_url) diff --git a/Library/Homebrew/cask/url.rbi b/Library/Homebrew/cask/url.rbi new file mode 100644 index 0000000000..6f32e1b3b2 --- /dev/null +++ b/Library/Homebrew/cask/url.rbi @@ -0,0 +1,6 @@ +# typed: strict +# typed: false + +class URL + include Kernel +end From 02b2abaa678b5e791522fb69cf17549991ae34dc Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Wed, 31 Mar 2021 06:15:06 +0200 Subject: [PATCH 10/11] Skip `url do` URLs in offline audit. --- Library/Homebrew/cask/audit.rb | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/Library/Homebrew/cask/audit.rb b/Library/Homebrew/cask/audit.rb index e548ebc943..80e05ec81e 100644 --- a/Library/Homebrew/cask/audit.rb +++ b/Library/Homebrew/cask/audit.rb @@ -308,7 +308,7 @@ module Cask LIVECHECK_REFERENCE_URL = "https://github.com/Homebrew/homebrew-cask/blob/HEAD/doc/cask_language_reference/stanzas/livecheck.md" def check_hosting_with_livecheck(livecheck_result:) - return if cask.appcast || cask.livecheckable? + return if block_url_offline? || cask.appcast || cask.livecheckable? return if livecheck_result == :auto_detected add_livecheck = "please add a livecheck. See #{Formatter.url(LIVECHECK_REFERENCE_URL)}" @@ -419,9 +419,16 @@ module Cask URI(cask.url.to_s).scheme == "file" end + def block_url_offline? + return false if online? + + cask.url.from_block? + end + VERIFIED_URL_REFERENCE_URL = "https://github.com/Homebrew/homebrew-cask/blob/master/doc/cask_language_reference/stanzas/url.md#when-url-and-homepage-hostnames-differ-add-verified" def check_unnecessary_verified + return if block_url_offline? return unless verified_present? return unless url_match_homepage? return unless verified_matches_url? @@ -432,7 +439,7 @@ module Cask end def check_missing_verified - return if cask.url.from_block? + return if block_url_offline? return if file_url? return if url_match_homepage? return if verified_present? @@ -443,6 +450,7 @@ module Cask end def check_no_match + return if block_url_offline? return unless verified_present? return if verified_matches_url? @@ -592,7 +600,7 @@ module Cask return if cask.tap == "homebrew/cask-versions" odebug "Auditing GitHub prerelease" - user, repo = get_repo_data(%r{https?://github\.com/([^/]+)/([^/]+)/?.*}) if @online + user, repo = get_repo_data(%r{https?://github\.com/([^/]+)/([^/]+)/?.*}) if online? return if user.nil? tag = SharedAudits.github_tag_from_url(cask.url) @@ -604,7 +612,7 @@ module Cask def check_gitlab_prerelease_version return if cask.tap == "homebrew/cask-versions" - user, repo = get_repo_data(%r{https?://gitlab\.com/([^/]+)/([^/]+)/?.*}) if @online + user, repo = get_repo_data(%r{https?://gitlab\.com/([^/]+)/([^/]+)/?.*}) if online? return if user.nil? odebug "Auditing GitLab prerelease" @@ -616,7 +624,7 @@ module Cask end def check_github_repository_archived - user, repo = get_repo_data(%r{https?://github\.com/([^/]+)/([^/]+)/?.*}) if @online + user, repo = get_repo_data(%r{https?://github\.com/([^/]+)/([^/]+)/?.*}) if online? return if user.nil? odebug "Auditing GitHub repo archived" @@ -636,7 +644,7 @@ module Cask end def check_gitlab_repository_archived - user, repo = get_repo_data(%r{https?://gitlab\.com/([^/]+)/([^/]+)/?.*}) if @online + user, repo = get_repo_data(%r{https?://gitlab\.com/([^/]+)/([^/]+)/?.*}) if online? return if user.nil? odebug "Auditing GitLab repo archived" From ffba81f6770769adf139df65bb1985bfdf2e3352 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Wed, 31 Mar 2021 06:25:33 +0200 Subject: [PATCH 11/11] Adjust `audit` spec. --- Library/Homebrew/test/cask/audit_spec.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/test/cask/audit_spec.rb b/Library/Homebrew/test/cask/audit_spec.rb index 168230fe31..5b12bb80fa 100644 --- a/Library/Homebrew/test/cask/audit_spec.rb +++ b/Library/Homebrew/test/cask/audit_spec.rb @@ -795,7 +795,17 @@ describe Cask::Audit, :cask do end end - context "when doing the audit" do + context "when doing an offline audit" do + let(:online) { false } + + it "does not evaluate the block" do + expect(run).not_to pass + end + end + + context "when doing and online audit" do + let(:online) { true } + it "evaluates the block" do expect(run).to fail_with(/Boom/) end