109 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| require "yaml"
 | |
| require "open3"
 | |
| require "stringio"
 | |
| 
 | |
| BUG_REPORTS_URL = "https://github.com/caskroom/homebrew-cask#reporting-bugs".freeze
 | |
| 
 | |
| class Buffer < StringIO
 | |
|   extend Predicable
 | |
| 
 | |
|   attr_predicate :tty?
 | |
| 
 | |
|   def initialize(tty = false)
 | |
|     super()
 | |
|     @tty = tty
 | |
|   end
 | |
| end
 | |
| 
 | |
| # global methods
 | |
| 
 | |
| def odebug(title, *sput)
 | |
|   return unless ARGV.debug?
 | |
|   puts Formatter.headline(title, color: :magenta)
 | |
|   puts sput unless sput.empty?
 | |
| end
 | |
| 
 | |
| module Hbc
 | |
|   module Utils
 | |
|     def self.gain_permissions_remove(path, command: SystemCommand)
 | |
|       if path.respond_to?(:rmtree) && path.exist?
 | |
|         gain_permissions(path, ["-R"], command) do |p|
 | |
|           if p.parent.writable?
 | |
|             p.rmtree
 | |
|           else
 | |
|             command.run("/bin/rm",
 | |
|                         args: ["-r", "-f", "--", p],
 | |
|                         sudo: true)
 | |
|           end
 | |
|         end
 | |
|       elsif File.symlink?(path)
 | |
|         gain_permissions(path, ["-h"], command, &FileUtils.method(:rm_f))
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     def self.gain_permissions(path, command_args, command)
 | |
|       tried_permissions = false
 | |
|       tried_ownership = false
 | |
|       begin
 | |
|         yield path
 | |
|       rescue StandardError
 | |
|         # in case of permissions problems
 | |
|         unless tried_permissions
 | |
|           # TODO: Better handling for the case where path is a symlink.
 | |
|           #       The -h and -R flags cannot be combined, and behavior is
 | |
|           #       dependent on whether the file argument has a trailing
 | |
|           #       slash.  This should do the right thing, but is fragile.
 | |
|           command.run("/usr/bin/chflags",
 | |
|                       must_succeed: false,
 | |
|                       args:         command_args + ["--", "000", path])
 | |
|           command.run("/bin/chmod",
 | |
|                       must_succeed: false,
 | |
|                       args:         command_args + ["--", "u+rwx", path])
 | |
|           command.run("/bin/chmod",
 | |
|                       must_succeed: false,
 | |
|                       args:         command_args + ["-N", path])
 | |
|           tried_permissions = true
 | |
|           retry # rmtree
 | |
|         end
 | |
|         unless tried_ownership
 | |
|           # in case of ownership problems
 | |
|           # TODO: Further examine files to see if ownership is the problem
 | |
|           #       before using sudo+chown
 | |
|           ohai "Using sudo to gain ownership of path '#{path}'"
 | |
|           command.run("/usr/sbin/chown",
 | |
|                       args: command_args + ["--", current_user, path],
 | |
|                       sudo: true)
 | |
|           tried_ownership = true
 | |
|           # retry chflags/chmod after chown
 | |
|           tried_permissions = false
 | |
|           retry # rmtree
 | |
|         end
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     def self.current_user
 | |
|       Etc.getpwuid(Process.euid).name
 | |
|     end
 | |
| 
 | |
|     def self.path_occupied?(path)
 | |
|       File.exist?(path) || File.symlink?(path)
 | |
|     end
 | |
| 
 | |
|     def self.error_message_with_suggestions
 | |
|       <<-EOS.undent
 | |
|         Follow the instructions here:
 | |
|           #{Formatter.url(BUG_REPORTS_URL)}
 | |
|       EOS
 | |
|     end
 | |
| 
 | |
|     def self.method_missing_message(method, token, section = nil)
 | |
|       poo = []
 | |
|       poo << "Unexpected method '#{method}' called"
 | |
|       poo << "during #{section}" if section
 | |
|       poo << "on Cask #{token}."
 | |
| 
 | |
|       opoo(poo.join(" ") + "\n" + error_message_with_suggestions)
 | |
|     end
 | |
|   end
 | |
| end
 | 
