diff --git a/Library/Homebrew/dev-cmd/bump-formula-pr.rb b/Library/Homebrew/dev-cmd/bump-formula-pr.rb index 4418d66d15ad054f8157e890376876c28b695283..116d192665517b7a3946a80d3015d97a6f2d7f57 100644 --- a/Library/Homebrew/dev-cmd/bump-formula-pr.rb +++ b/Library/Homebrew/dev-cmd/bump-formula-pr.rb @@ -18,7 +18,11 @@ module Homebrew be made if either or both values are not supplied by the user. If a <tag> is specified, the Git commit <revision> corresponding to that tag - must also be specified. + should also be specified. A best effort to determine the <revision> will be made + if the value is not supplied by the user. + + If a <version> is specified, a best effort to determine the <URL> and <SHA-256> or + the <tag> and <revision> will be made if both values are not supplied by the user. *Note:* this command cannot be used to transition a formula from a URL-and-SHA-256 style specification into a tag-and-revision style specification, @@ -58,8 +62,8 @@ module Homebrew flag "--tag=", description: "Specify the new git commit <tag> for the formula." flag "--revision=", - required_for: "--tag=", - description: "Specify the new git commit <revision> corresponding to the specified <tag>." + depends_on: "--tag=", + description: "Specify the new git commit <revision> corresponding to the specified <tag>." switch :force switch :quiet switch :verbose @@ -119,31 +123,7 @@ module Homebrew formula = args.formulae.first new_url = args.url - if new_url && !formula - # Split the new URL on / and find any formulae that have the same URL - # except for the last component, but don't try to match any more than the - # first five components since sometimes the last component isn't the only - # one to change. - new_url_split = new_url.split("/") - maximum_url_components_to_match = 5 - components_to_match = [new_url_split.count - 1, maximum_url_components_to_match].min - base_url = new_url_split.first(components_to_match).join("/") - base_url = /#{Regexp.escape(base_url)}/ - is_devel = args.devel? - guesses = [] - Formula.each do |f| - if is_devel && f.devel && f.devel.url && f.devel.url.match(base_url) - guesses << f - elsif f.stable&.url && f.stable.url.match(base_url) - guesses << f - end - end - if guesses.count == 1 - formula = guesses.shift - elsif guesses.count > 1 - odie "Couldn't guess formula for sure; could be one of these:\n#{guesses.map(&:name).join(", ")}" - end - end + formula ||= determine_formula_from_url(new_url, args.devel?) if new_url raise FormulaUnspecifiedError unless formula tap_full_name, origin_branch, previous_branch = use_correct_linux_tap(formula) @@ -175,28 +155,41 @@ module Homebrew new_url.sub "mirrors.ocf.berkeley.edu/debian", "mirrorservice.org/sites/ftp.debian.org/debian" end new_mirrors ||= [new_mirror] unless new_mirror.nil? - forced_version = args.version + new_version = args.version + old_url = formula_spec.url + old_tag = formula_spec.specs[:tag] + old_formula_version = formula_version(formula, requested_spec) + old_version = old_formula_version.to_s + forced_version = false new_url_hash = if new_url && new_hash true elsif new_tag && new_revision false elsif !hash_type - odie "#{formula}: no --tag=/--revision= arguments specified!" - elsif !new_url - odie "#{formula}: no --url= argument specified!" + odie "#{formula}: no --tag= or --version= argument specified!" if !new_tag && !new_version + new_tag ||= old_tag.gsub(old_version, new_version) + if new_tag == old_tag + odie <<~EOS + You probably need to bump this formula manually since the new tag + and old tag are both #{new_tag}. + EOS + end + resource_path, forced_version = fetch_resource(formula, new_version, old_url, tag: new_tag) + new_revision = Utils.popen_read("git -C \"#{resource_path}\" rev-parse -q --verify HEAD") + new_revision = new_revision.strip + false + elsif !new_url && !new_version + odie "#{formula}: no --url= or --version= argument specified!" else - resource = Resource.new { @url = new_url } - resource.download_strategy = DownloadStrategyDetector.detect_from_url(new_url) - resource.owner = Resource.new(formula.name) - if forced_version - if forced_version == resource.version - forced_version = nil - else - resource.version = forced_version - end + new_url ||= old_url.gsub(old_version, new_version) + if new_url == old_url + odie <<~EOS + You probably need to bump this formula manually since the new URL + and old URL are both: + #{new_url} + EOS end - odie "No --version= argument specified!" unless resource.version - resource_path = resource.fetch + resource_path, forced_version = fetch_resource(formula, new_version, new_url) tar_file_extensions = %w[.tar .tb2 .tbz .tbz2 .tgz .tlz .txz .tZ] if tar_file_extensions.any? { |extension| new_url.include? extension } gnu_tar_gtar_path = HOMEBREW_PREFIX/"opt/gnu-tar/bin/gtar" @@ -212,8 +205,6 @@ module Homebrew end end - old_formula_version = formula_version(formula, requested_spec) - replacement_pairs = [] if requested_spec == :stable && formula.revision.nonzero? replacement_pairs << [ @@ -273,32 +264,32 @@ module Homebrew ] end - if forced_version && forced_version != "0" + if forced_version && new_version != "0" case requested_spec when :stable replacement_pairs << if File.read(formula.path).include?("version \"#{old_formula_version}\"") [ old_formula_version.to_s, - forced_version, + new_version, ] elsif new_mirrors [ /^( +)(mirror "#{Regexp.escape(new_mirrors.last)}"\n)/m, - "\\1\\2\\1version \"#{forced_version}\"\n", + "\\1\\2\\1version \"#{new_version}\"\n", ] else [ /^( +)(url "#{Regexp.escape(new_url)}"\n)/m, - "\\1\\2\\1version \"#{forced_version}\"\n", + "\\1\\2\\1version \"#{new_version}\"\n", ] end when :devel replacement_pairs << [ /( devel do.+?version ")#{old_formula_version}("\n.+?end\n)/m, - "\\1#{forced_version}\\2", + "\\1#{new_version}\\2", ] end - elsif forced_version && forced_version == "0" + elsif forced_version && new_version == "0" case requested_spec when :stable replacement_pairs << [ @@ -312,7 +303,7 @@ module Homebrew ] end end - new_contents = inreplace_pairs(formula.path, replacement_pairs) + new_contents = inreplace_pairs(formula.path, replacement_pairs.uniq) new_formula_version = formula_version(formula, requested_spec, new_contents) @@ -413,6 +404,40 @@ module Homebrew end end + def determine_formula_from_url(url, is_devel) + # Split the new URL on / and find any formulae that have the same URL + # except for the last component, but don't try to match any more than the + # first five components since sometimes the last component isn't the only + # one to change. + url_split = url.split("/") + maximum_url_components_to_match = 5 + components_to_match = [url_split.count - 1, maximum_url_components_to_match].min + base_url = url_split.first(components_to_match).join("/") + base_url = /#{Regexp.escape(base_url)}/ + guesses = [] + Formula.each do |f| + if is_devel && f.devel && f.devel.url && f.devel.url.match(base_url) + guesses << f + elsif f.stable&.url && f.stable.url.match(base_url) + guesses << f + end + end + return guesses.shift if guesses.count == 1 + return unless guesses.count > 1 + + odie "Couldn't guess formula for sure; could be one of these:\n#{guesses.map(&:name).join(", ")}" + end + + def fetch_resource(formula, new_version, url, **specs) + resource = Resource.new + resource.url(url, specs) + resource.owner = Resource.new(formula.name) + forced_version = new_version && new_version != resource.version + resource.version = new_version if forced_version + odie "No --version= argument specified!" unless resource.version + [resource.fetch, forced_version] + end + def forked_repo_info(formula, tap_full_name, backup_file) response = GitHub.create_fork(tap_full_name) rescue GitHub::AuthenticationFailedError, *GitHub.api_errors => e diff --git a/docs/Manpage.md b/docs/Manpage.md index 9400e9641082b68e3b8127db46dcb7aec9a320e3..64cf84e86a0807998649ed1b2d2ffcf47d214302 100644 --- a/docs/Manpage.md +++ b/docs/Manpage.md @@ -707,7 +707,12 @@ be specified. A best effort to determine the *`SHA-256`* and *`formula`* name wi be made if either or both values are not supplied by the user. If a *`tag`* is specified, the Git commit *`revision`* corresponding to that tag -must also be specified. +should also be specified. A best effort to determine the *`revision`* will be made +if the value is not supplied by the user. + +If a *`version`* is specified, a best effort to determine the *`URL`* and *`SHA-256`* +or the *`tag`* and *`revision`* will be made if both values are not supplied by the +user. *Note:* this command cannot be used to transition a formula from a URL-and-SHA-256 style specification into a tag-and-revision style specification, diff --git a/manpages/brew.1 b/manpages/brew.1 index 0442395eedad3c21d80af0cef7f6f7f9192c9ba1..8cb2c10c71f1deabe60e8a0b1690a1f69acb5017 100644 --- a/manpages/brew.1 +++ b/manpages/brew.1 @@ -917,7 +917,10 @@ Create a pull request to update \fIformula\fR with a new URL or a new tag\. If a \fIURL\fR is specified, the \fISHA\-256\fR checksum of the new download should also be specified\. A best effort to determine the \fISHA\-256\fR and \fIformula\fR name will be made if either or both values are not supplied by the user\. . .P -If a \fItag\fR is specified, the Git commit \fIrevision\fR corresponding to that tag must also be specified\. +If a \fItag\fR is specified, the Git commit \fIrevision\fR corresponding to that tag should also be specified\. A best effort to determine the \fIrevision\fR will be made if the value is not supplied by the user\. +. +.P +If a \fIversion\fR is specified, a best effort to determine the \fIURL\fR and \fISHA\-256\fR or the \fItag\fR and \fIrevision\fR will be made if both values are not supplied by the user\. . .P \fINote:\fR this command cannot be used to transition a formula from a URL\-and\-SHA\-256 style specification into a tag\-and\-revision style specification, nor vice versa\. It must use whichever style specification the formula already uses\.