Skip to content

Commit

Permalink
update-report: allow additions/deletions from the API.
Browse files Browse the repository at this point in the history
If we're installing from the API: we cannot use Git to check for differences in
packages so instead use `{formula,cask}_names.txt` to do so.

The first time this runs: we won't yet have a base state
(`{formula,cask}_names.before.txt`) to compare against so we don't output
anything and just copy the files for next time.
  • Loading branch information
MikeMcQuaid committed Feb 28, 2023
1 parent 1201f18 commit 2451d01
Showing 1 changed file with 83 additions and 17 deletions.
100 changes: 83 additions & 17 deletions Library/Homebrew/cmd/update-report.rb
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,40 @@ def output_update_report
end
end

# If we're installing from the API: we cannot use Git to check for #
# differences in packages so instead use {formula,cask}_names.txt to do so.
# The first time this runs: we won't yet have a base state
# ({formula,cask}_names.before.txt) to compare against so we don't output a
# anything and just copy the files for next time.
unless Homebrew::EnvConfig.no_install_from_api?
api_cache = Homebrew::API::HOMEBREW_CACHE_API
core_tap = CoreTap.instance
cask_tap = Tap.fetch("homebrew/cask")
[
[:formula, core_tap, core_tap.formula_dir],
[:cask, cask_tap, cask_tap.cask_dir],
].each do |type, tap, dir|
names_txt = api_cache/"#{type}_names.txt"
next unless names_txt.exist?

names_before_txt = api_cache/"#{type}_names.before.txt"
if names_before_txt.exist?
reporter = Reporter.new(
tap,
api_names_txt: names_txt,
api_names_before_txt: names_before_txt,
api_dir_prefix: dir,
)
if reporter.updated?
updated_taps << tap.name
hub.add(reporter, auto_update: args.auto_update?)
end
end

FileUtils.cp names_txt, names_before_txt
end
end

unless updated_taps.empty?
auto_update_header args: args
noun = Utils.pluralize("tap", updated_taps.count)
Expand Down Expand Up @@ -278,9 +312,7 @@ def install_core_tap_if_necessary
return if ENV["HOMEBREW_UPDATE_TEST"]
return unless Homebrew::EnvConfig.no_install_from_api?
return if Homebrew::EnvConfig.automatically_set_no_install_from_api?

core_tap = CoreTap.instance
return if core_tap.installed?
return if CoreTap.instance.installed?

CoreTap.ensure_installed!
revision = core_tap.git_head
Expand Down Expand Up @@ -314,18 +346,23 @@ def initialize(var_name)
end
end

attr_reader :tap, :initial_revision, :current_revision

def initialize(tap)
def initialize(tap, api_names_txt: nil, api_names_before_txt: nil, api_dir_prefix: nil)
@tap = tap

initial_revision_var = "HOMEBREW_UPDATE_BEFORE#{tap.repo_var}"
@initial_revision = ENV[initial_revision_var].to_s
raise ReporterRevisionUnsetError, initial_revision_var if @initial_revision.empty?
# This is slightly involved/weird but all the #report logic is shared so it's worth it.
if installed_from_api?(api_names_txt, api_names_before_txt, api_dir_prefix)
@api_names_txt = api_names_txt
@api_names_before_txt = api_names_before_txt
@api_dir_prefix = api_dir_prefix
else
initial_revision_var = "HOMEBREW_UPDATE_BEFORE#{tap.repo_var}"
@initial_revision = ENV[initial_revision_var].to_s
raise ReporterRevisionUnsetError, initial_revision_var if @initial_revision.empty?

current_revision_var = "HOMEBREW_UPDATE_AFTER#{tap.repo_var}"
@current_revision = ENV[current_revision_var].to_s
raise ReporterRevisionUnsetError, current_revision_var if @current_revision.empty?
current_revision_var = "HOMEBREW_UPDATE_AFTER#{tap.repo_var}"
@current_revision = ENV[current_revision_var].to_s
raise ReporterRevisionUnsetError, current_revision_var if @current_revision.empty?
end
end

def report(auto_update: false)
Expand Down Expand Up @@ -417,7 +454,11 @@ def report(auto_update: false)
end

def updated?
initial_revision != current_revision
if installed_from_api?
diff.present?
else
initial_revision != current_revision
end
end

def migrate_tap_migration
Expand Down Expand Up @@ -529,11 +570,36 @@ def migrate_formula_rename(force:, verbose:)

private

attr_reader :tap, :initial_revision, :current_revision, :api_names_txt, :api_names_before_txt, :api_dir_prefix

def installed_from_api?(api_names_txt = @api_names_txt, api_names_before_txt = @api_names_before_txt,
api_dir_prefix = @api_dir_prefix)
!api_names_txt.nil? && !api_names_before_txt.nil? && !api_dir_prefix.nil?
end

def diff
Utils.popen_read(
"git", "-C", tap.path, "diff-tree", "-r", "--name-status", "--diff-filter=AMDR",
"-M85%", initial_revision, current_revision
)
@diff ||= if installed_from_api?
# Hack `git diff` output with regexes to look like `git diff-tree` output.
# Yes, I know this is a bit filthy but it saves duplicating the #report logic.
diff_output = Utils.popen_read("git", "diff", api_names_txt, api_names_before_txt)
header_regex = /^(---|\+\+\+) /.freeze
add_delete_characters = ["+", "-"].freeze

diff_output.lines.map do |line|
next if line.match?(header_regex)
next unless add_delete_characters.include?(line[0])

line.sub(/^\+/, "A #{api_dir_prefix.basename}/")
.sub(/^-/, "D #{api_dir_prefix.basename}/")
.sub(/$/, ".rb")
.chomp
end.compact.join("\n")
else
Utils.popen_read(
"git", "-C", tap.path, "diff-tree", "-r", "--name-status", "--diff-filter=AMDR",
"-M85%", initial_revision, current_revision
)
end
end
end

Expand Down

0 comments on commit 2451d01

Please sign in to comment.