Skip to content
Snippets Groups Projects
Commit 0a4fbf7f authored by Seeker's avatar Seeker
Browse files

dev-cmd: add `bump-cask-pr`

parent be92ef28
No related branches found
No related tags found
No related merge requests found
# frozen_string_literal: true
require "cask"
require "cli/parser"
require "utils/tar"
module Homebrew
module_function
def bump_cask_pr_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`bump-cask-pr` [<options>] [<cask>]
Create a pull request to update <cask> with a new version.
A best effort to determine the <SHA-256> will be made if the value is not
supplied by the user.
EOS
switch "-n", "--dry-run",
description: "Print what would be done rather than doing it."
switch "--write",
description: "Make the expected file modifications without taking any Git actions."
switch "--commit",
depends_on: "--write",
description: "When passed with `--write`, generate a new commit after writing changes "\
"to the cask file."
switch "--no-audit",
description: "Don't run `brew cask audit` before opening the PR."
switch "--no-style",
description: "Don't run `brew cask style --fix` before opening the PR."
switch "--no-browse",
description: "Print the pull request URL instead of opening in a browser."
switch "--no-fork",
description: "Don't try to fork the repository."
flag "--version=",
description: "Specify the new <version> for the cask."
flag "--message=",
description: "Append <message> to the default pull request message."
flag "--url=",
description: "Specify the <URL> for the new download."
flag "--sha256=",
description: "Specify the <SHA-256> checksum of the new download."
switch "-f", "--force",
description: "Ignore duplicate open PRs."
conflicts "--dry-run", "--write"
named 1
end
end
def bump_cask_pr
args = bump_cask_pr_args.parse
# As this command is simplifying user-run commands then let's just use a
# user path, too.
ENV["PATH"] = ENV["HOMEBREW_PATH"]
# Use the user's browser, too.
ENV["BROWSER"] = Homebrew::EnvConfig.browser
cask = args.named.to_casks.first
new_version = args.version
new_base_url = args.url
new_hash = args.sha256
old_version = cask.version
old_hash = cask.sha256
tap_full_name = cask.tap&.full_name
origin_branch = Utils::Git.origin_branch(cask.tap.path) if cask.tap
origin_branch ||= "origin/master"
previous_branch = "-"
check_open_pull_requests(cask, tap_full_name, args: args)
odie "#{cask}: no --version= argument specified!" unless new_version
check_closed_pull_requests(cask, tap_full_name, version: new_version, args: args)
if Version.new(new_version) < Version.new(old_version)
odie <<~EOS
You need to bump this cask manually since changing the
version from #{old_version} to #{new_version} would be a downgrade.
EOS
elsif new_version == old_version
odie <<~EOS
You need to bump this cask manually since the new version
and old version are both #{new_version}.
EOS
end
old_contents = File.read(cask.sourcefile_path)
replacement_pairs = [
[
old_version,
new_version,
],
]
if new_base_url.present?
m = /^ +url "(.+?)"\n/m.match(old_contents)
odie "Could not find old URL in cask!" if m.nil?
old_base_url = m.captures.first
replacement_pairs << [
/#{Regexp.escape(old_base_url)}/,
new_base_url,
]
end
if new_hash.nil? || cask.languages.present?
tmp_contents = Utils::Inreplace.inreplace_pairs(cask.sourcefile_path,
replacement_pairs.uniq.compact,
read_only_run: true,
silent: true)
tmp_cask = Cask::CaskLoader.load(tmp_contents)
tmp_url = tmp_cask.url.to_s
if new_hash.nil?
resource_path = fetch_resource(cask, new_version, tmp_url)
Utils::Tar.validate_file(resource_path)
new_hash = resource_path.sha256
end
cask.languages.each do |language|
next if language == cask.language
tmp_cask.config.languages = [language]
lang_cask = Cask::CaskLoader.load(tmp_contents)
lang_url = lang_cask.url.to_s
lang_old_hash = lang_cask.sha256
resource_path = fetch_resource(cask, new_version, lang_url)
Utils::Tar.validate_file(resource_path)
lang_new_hash = resource_path.sha256
replacement_pairs << [
lang_old_hash,
lang_new_hash,
]
end
end
replacement_pairs << [
old_hash,
new_hash,
]
Utils::Inreplace.inreplace_pairs(cask.sourcefile_path,
replacement_pairs.uniq.compact,
read_only_run: args.dry_run?,
silent: args.quiet?)
run_cask_audit(cask, old_contents, args: args)
run_cask_style(cask, old_contents, args: args)
pr_info = {
sourcefile_path: cask.sourcefile_path,
old_contents: old_contents,
origin_branch: origin_branch,
branch_name: "bump-#{cask.token}-#{new_version}",
commit_message: "Update #{cask.token} from #{old_version} to #{new_version}",
previous_branch: previous_branch,
tap: cask.tap,
tap_full_name: tap_full_name,
pr_message: "Created with `brew bump-cask-pr`.",
}
GitHub.create_bump_pr(pr_info, args: args)
end
def fetch_resource(cask, new_version, url, **specs)
resource = Resource.new
resource.url(url, specs)
resource.owner = Resource.new(cask.token)
resource.version = new_version
resource.fetch
end
def check_open_pull_requests(cask, tap_full_name, args:)
GitHub.check_for_duplicate_pull_requests(cask.token, tap_full_name, state: "open", args: args)
end
def check_closed_pull_requests(cask, tap_full_name, version:, args:)
# if we haven't already found open requests, try for an exact match across closed requests
pr_title = "Update #{cask.token} from #{cask.version} to #{version}"
GitHub.check_for_duplicate_pull_requests(pr_title, tap_full_name, state: "closed", args: args)
end
def run_cask_audit(cask, old_contents, args:)
if args.dry_run?
if args.no_audit?
ohai "Skipping `brew cask audit`"
else
ohai "brew cask audit #{cask.sourcefile_path.basename}"
end
return
end
failed_audit = false
if args.no_audit?
ohai "Skipping `brew cask audit`"
else
system HOMEBREW_BREW_FILE, "cask", "audit", cask.sourcefile_path
failed_audit = !$CHILD_STATUS.success?
end
return unless failed_audit
cask.sourcefile_path.atomic_write(old_contents)
odie "`brew cask audit` failed!"
end
def run_cask_style(cask, old_contents, args:)
if args.dry_run?
if args.no_style?
ohai "Skipping `brew cask style --fix`"
else
ohai "brew cask style --fix #{cask.sourcefile_path.basename}"
end
return
end
failed_style = false
if args.no_style?
ohai "Skipping `brew cask style --fix`"
else
system HOMEBREW_BREW_FILE, "cask", "style", "--fix", cask.sourcefile_path
failed_style = !$CHILD_STATUS.success?
end
return unless failed_style
cask.sourcefile_path.atomic_write(old_contents)
odie "`brew cask style --fix` failed!"
end
end
# frozen_string_literal: true
require "cmd/shared_examples/args_parse"
describe "Homebrew.bump_cask_pr_args" do
it_behaves_like "parseable arguments"
end
......@@ -14,6 +14,7 @@ analytics
audit
bottle
bump
bump-cask-pr
bump-formula-pr
bump-revision
cask
......
......@@ -819,6 +819,38 @@ Also displays whether a pull request has been opened with the URL.
* `--limit`:
Limit number of package results returned.
### `bump-cask-pr` [*`options`*] [*`cask`*]
Create a pull request to update *`cask`* with a new version.
A best effort to determine the *`SHA-256`* will be made if the value is not
supplied by the user.
* `-n`, `--dry-run`:
Print what would be done rather than doing it.
* `--write`:
Make the expected file modifications without taking any Git actions.
* `--commit`:
When passed with `--write`, generate a new commit after writing changes to the cask file.
* `--no-audit`:
Don't run `brew cask audit` before opening the PR.
* `--no-style`:
Don't run `brew cask style --fix` before opening the PR.
* `--no-browse`:
Print the pull request URL instead of opening in a browser.
* `--no-fork`:
Don't try to fork the repository.
* `--version`:
Specify the new *`version`* for the cask.
* `--message`:
Append *`message`* to the default pull request message.
* `--url`:
Specify the *`URL`* for the new download.
* `--sha256`:
Specify the *`SHA-256`* checksum of the new download.
* `-f`, `--force`:
Ignore duplicate open PRs.
### `bump-formula-pr` [*`options`*] [*`formula`*]
Create a pull request to update *`formula`* with a new URL or a new tag.
......
......@@ -1134,6 +1134,60 @@ Display out\-of\-date brew formulae and the latest version available\. Also disp
\fB\-\-limit\fR
Limit number of package results returned\.
.
.SS "\fBbump\-cask\-pr\fR [\fIoptions\fR] [\fIcask\fR]"
Create a pull request to update \fIcask\fR with a new version\.
.
.P
A best effort to determine the \fISHA\-256\fR will be made if the value is not supplied by the user\.
.
.TP
\fB\-n\fR, \fB\-\-dry\-run\fR
Print what would be done rather than doing it\.
.
.TP
\fB\-\-write\fR
Make the expected file modifications without taking any Git actions\.
.
.TP
\fB\-\-commit\fR
When passed with \fB\-\-write\fR, generate a new commit after writing changes to the cask file\.
.
.TP
\fB\-\-no\-audit\fR
Don\'t run \fBbrew cask audit\fR before opening the PR\.
.
.TP
\fB\-\-no\-style\fR
Don\'t run \fBbrew cask style \-\-fix\fR before opening the PR\.
.
.TP
\fB\-\-no\-browse\fR
Print the pull request URL instead of opening in a browser\.
.
.TP
\fB\-\-no\-fork\fR
Don\'t try to fork the repository\.
.
.TP
\fB\-\-version\fR
Specify the new \fIversion\fR for the cask\.
.
.TP
\fB\-\-message\fR
Append \fImessage\fR to the default pull request message\.
.
.TP
\fB\-\-url\fR
Specify the \fIURL\fR for the new download\.
.
.TP
\fB\-\-sha256\fR
Specify the \fISHA\-256\fR checksum of the new download\.
.
.TP
\fB\-f\fR, \fB\-\-force\fR
Ignore duplicate open PRs\.
.
.SS "\fBbump\-formula\-pr\fR [\fIoptions\fR] [\fIformula\fR]"
Create a pull request to update \fIformula\fR with a new URL or a new tag\.
.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment