Module: Utils

Included in:
Hbc
Defined in:
Library/Homebrew/utils/git.rb,
Library/Homebrew/utils/svn.rb,
Library/Homebrew/utils/fork.rb,
Library/Homebrew/utils/link.rb,
Library/Homebrew/utils/popen.rb,
Library/Homebrew/utils/shell.rb,
Library/Homebrew/utils/bottles.rb,
Library/Homebrew/utils/analytics.rb,
Library/Homebrew/utils/inreplace.rb,
Library/Homebrew/extend/os/mac/utils/bottles.rb

Defined Under Namespace

Modules: Analytics, Inreplace, Link, Shell Classes: Bottles, InreplaceError

Class Method Summary collapse

Class Method Details

.clear_git_available_cacheObject



63
64
65
66
67
# File 'Library/Homebrew/utils/git.rb', line 63

def self.clear_git_available_cache
  @git = nil
  @git_path = nil
  @git_version = nil
end

.clear_svn_version_cacheObject



2
3
4
# File 'Library/Homebrew/utils/svn.rb', line 2

def self.clear_svn_version_cache
  remove_instance_variable(:@svn) if instance_variable_defined?(:@svn)
end

.ensure_git_installed!Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'Library/Homebrew/utils/git.rb', line 47

def self.ensure_git_installed!
  return if git_available?

  # we cannot install brewed git if homebrew/core is unavailable.
  if CoreTap.instance.installed?
    begin
      oh1 "Installing #{Formatter.identifier("git")}"
      safe_system HOMEBREW_BREW_FILE, "install", "git"
    rescue
      raise "Git is unavailable"
    end
  end

  raise "Git is unavailable" unless git_available?
end

.git_available?Boolean

Returns:

  • (Boolean)


29
30
31
# File 'Library/Homebrew/utils/git.rb', line 29

def self.git_available?
  @git ||= quiet_system HOMEBREW_SHIMS_PATH/"scm/git", "--version"
end

.git_pathObject



33
34
35
36
37
38
# File 'Library/Homebrew/utils/git.rb', line 33

def self.git_path
  return unless git_available?
  @git_path ||= Utils.popen_read(
    HOMEBREW_SHIMS_PATH/"scm/git", "--homebrew=print-path"
  ).chuzzle
end

.git_remote_exists(url) ⇒ Object



69
70
71
72
# File 'Library/Homebrew/utils/git.rb', line 69

def self.git_remote_exists(url)
  return true unless git_available?
  quiet_system "git", "ls-remote", url
end

.git_versionObject



40
41
42
43
44
45
# File 'Library/Homebrew/utils/git.rb', line 40

def self.git_version
  return unless git_available?
  @git_version ||= Utils.popen_read(
    HOMEBREW_SHIMS_PATH/"scm/git", "--version"
  ).chomp[/git version (\d+(?:\.\d+)*)/, 1]
end

.popen(args, mode, options = {}) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'Library/Homebrew/utils/popen.rb', line 10

def self.popen(args, mode, options = {})
  IO.popen("-", mode) do |pipe|
    if pipe
      return pipe.read unless block_given?
      yield pipe
    else
      options[:err] ||= :close unless ENV["HOMEBREW_STDERR"]
      begin
        exec(*args, options)
      rescue Errno::ENOENT
        $stderr.puts "brew: command not found: #{args[0]}" unless options[:err] == :close
        exit! 127
      rescue SystemCallError
        $stderr.puts "brew: exec failed: #{args[0]}" unless options[:err] == :close
        exit! 1
      end
    end
  end
end

.popen_read(*args, **options, &block) ⇒ Object



2
3
4
# File 'Library/Homebrew/utils/popen.rb', line 2

def self.popen_read(*args, **options, &block)
  popen(args, "rb", options, &block)
end

.popen_write(*args, **options, &block) ⇒ Object



6
7
8
# File 'Library/Homebrew/utils/popen.rb', line 6

def self.popen_write(*args, **options, &block)
  popen(args, "wb", options, &block)
end

.safe_fork(&_block) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'Library/Homebrew/utils/fork.rb', line 5

def self.safe_fork(&_block)
  Dir.mktmpdir("homebrew", HOMEBREW_TEMP) do |tmpdir|
    UNIXServer.open("#{tmpdir}/socket") do |server|
      read, write = IO.pipe

      pid = fork do
        begin
          ENV["HOMEBREW_ERROR_PIPE"] = server.path
          server.close
          read.close
          write.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
          yield
        rescue Exception => e # rubocop:disable Lint/RescueException
          Marshal.dump(e, write)
          write.close
          exit!
        else
          exit!(true)
        end
      end

      ignore_interrupts(:quietly) do # the child will receive the interrupt and marshal it back
        begin
          socket = server.accept_nonblock
        # rubocop:disable Lint/ShadowedException
        # FIXME: https://github.com/bbatsov/rubocop/issues/4843
        rescue Errno::EAGAIN, Errno::EWOULDBLOCK, Errno::ECONNABORTED, Errno::EPROTO, Errno::EINTR
          retry unless Process.waitpid(pid, Process::WNOHANG)
        # rubocop:enable Lint/ShadowedException
        else
          socket.send_io(write)
          socket.close
        end
        write.close
        data = read.read
        read.close
        Process.wait(pid) unless socket.nil?
        raise Marshal.load(data) unless data.nil? || data.empty? # rubocop:disable Security/MarshalLoad
        raise Interrupt if $CHILD_STATUS.exitstatus == 130
        raise "Forked child process failed: #{$CHILD_STATUS}" unless $CHILD_STATUS.success?
      end
    end
  end
end

.svn_available?Boolean

Returns:

  • (Boolean)


6
7
8
9
# File 'Library/Homebrew/utils/svn.rb', line 6

def self.svn_available?
  return @svn if instance_variable_defined?(:@svn)
  @svn = quiet_system HOMEBREW_SHIMS_PATH/"scm/svn", "--version"
end

.svn_remote_exists(url) ⇒ Object



11
12
13
14
# File 'Library/Homebrew/utils/svn.rb', line 11

def self.svn_remote_exists(url)
  return true unless svn_available?
  quiet_system "svn", "ls", url, "--depth", "empty"
end