From 4b0d52ef62c9e964b2a570b9e9459f454f311255 Mon Sep 17 00:00:00 2001 From: Lukas Oberhuber Date: Sun, 31 Jul 2022 19:59:25 +0100 Subject: [PATCH] debug_symbols passed down to soure dir creator The flag is now passed down to resource which creates the directory for unpacking the source. --- Library/Homebrew/formula.rb | 6 +-- Library/Homebrew/mksource.rb | 84 ++++++++++++++++++++++++++++++++++++ Library/Homebrew/resource.rb | 13 +++--- 3 files changed, 94 insertions(+), 9 deletions(-) create mode 100644 Library/Homebrew/mksource.rb diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index 87084de97d..e5b3dc8c15 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -1276,7 +1276,7 @@ class Formula def brew(fetch: true, keep_tmp: false, debug_symbols: false, interactive: false) @prefix_returns_versioned_prefix = true active_spec.fetch if fetch - stage(interactive: interactive) do |staging| + stage(interactive: interactive, debug_symbols: debug_symbols) do |staging| staging.retain! if keep_tmp || debug_symbols prepare_patches @@ -2437,8 +2437,8 @@ class Formula } end - def stage(interactive: false) - active_spec.stage do |staging| + def stage(interactive: false, debug_symbols: false) + active_spec.stage(debug_symbols: debug_symbols) do |staging| @source_modified_time = active_spec.source_modified_time @buildpath = Pathname.pwd env_home = buildpath/".brew_home" diff --git a/Library/Homebrew/mksource.rb b/Library/Homebrew/mksource.rb new file mode 100644 index 0000000000..8dc93af6cc --- /dev/null +++ b/Library/Homebrew/mksource.rb @@ -0,0 +1,84 @@ +# typed: false +# frozen_string_literal: true + +# Performs {Formula#mktemp}'s functionality, and tracks the results. +# Each instance is only intended to be used once. +class Mksource + extend T::Sig + + include FileUtils + + # Path to the tmpdir used in this run, as a {Pathname}. + attr_reader :tmpdir + + def initialize(prefix, opts = {}) + @prefix = prefix + @retain = opts[:retain] + @quiet = false + end + + # Instructs this {Mksource} to retain the staged files. + sig { void } + def retain! + @retain = true + end + + # True if the staged temporary files should be retained. + def retain? + @retain + end + + # Instructs this Mksource to not emit messages when retention is triggered. + sig { void } + def quiet! + @quiet = true + end + + sig { returns(String) } + def to_s + "[Mksource: #{tmpdir} retain=#{@retain} quiet=#{@quiet}]" + end + + def run + @tmpdir = Pathname.new(Dir.mktmpdir("#{@prefix.tr "@", "AT"}-", HOMEBREW_TEMP)) + + # Make sure files inside the temporary directory have the same group as the + # brew instance. + # + # Reference from `man 2 open` + # > When a new file is created, it is given the group of the directory which + # contains it. + group_id = if HOMEBREW_BREW_FILE.grpowned? + HOMEBREW_BREW_FILE.stat.gid + else + Process.gid + end + begin + chown(nil, group_id, tmpdir) + rescue Errno::EPERM + opoo "Failed setting group \"#{Etc.getgrgid(group_id).name}\" on #{tmpdir}" + end + + begin + Dir.chdir(tmpdir) { yield self } + ensure + ignore_interrupts { chmod_rm_rf(tmpdir) } unless retain? + end + ensure + ohai "Temporary files retained at:", @tmpdir.to_s if retain? && !@tmpdir.nil? && !@quiet + end + + private + + def chmod_rm_rf(path) + if path.directory? && !path.symlink? + chmod("u+rw", path) if path.owned? # Need permissions in order to see the contents + path.children.each { |child| chmod_rm_rf(child) } + rmdir(path) + else + rm_f(path) + end + rescue + nil # Just skip this directory. + end +end diff --git a/Library/Homebrew/resource.rb b/Library/Homebrew/resource.rb index a8e5f712c3..834b30ea0d 100644 --- a/Library/Homebrew/resource.rb +++ b/Library/Homebrew/resource.rb @@ -5,6 +5,7 @@ require "download_strategy" require "checksum" require "version" require "mktemp" +require "mksource" require "livecheck" require "extend/on_system" @@ -89,14 +90,14 @@ class Resource # dir using {Mktemp} so that works with all subtypes. # # @api public - def stage(target = nil, &block) + def stage(target = nil, debug_symbols: false, &block) raise ArgumentError, "target directory or block is required" if !target && block.blank? prepare_patches fetch_patches(skip_downloaded: true) fetch unless downloaded? - unpack(target, &block) + unpack(target, debug_symbols: debug_symbols, &block) end def prepare_patches @@ -120,9 +121,9 @@ class Resource # If block is given, yield to that block with `|stage|`, where stage # is a {ResourceStageContext}. # A target or a block must be given, but not both. - def unpack(target = nil) + def unpack(target = nil, debug_symbols: false) current_working_directory = Pathname.pwd - mktemp(download_name) do |staging| + stage_resource(download_name, debug_symbols: debug_symbols) do |staging| downloader.stage do @source_modified_time = downloader.source_modified_time apply_patches @@ -235,8 +236,8 @@ class Resource protected - def mktemp(prefix, &block) - Mktemp.new(prefix).run(&block) + def stage_resource(prefix, debug_symbols: false, &block) + debug_symbols ? Mksource.new(prefix).run(&block) : Mktemp.new(prefix).run(&block) end private