Class: Pathname

Inherits:
Object
  • Object
show all
Includes:
DiskUsageExtension, MachOShim
Defined in:
Library/Homebrew/extend/pathname.rb,
Library/Homebrew/extend/os/mac/extend/pathname.rb,
Library/Homebrew/extend/os/linux/extend/pathname.rb

Overview

Homebrew extends Ruby's Pathname to make our code more readable.

Instance Method Summary collapse

Methods included from MachOShim

#arch, #archs, #dylib_id, #dynamically_linked_libraries, #i386?, #ppc64?, #ppc7400?, #universal?, #x86_64?

Methods included from DiskUsageExtension

#abv, #disk_usage, #file_count

Instance Method Details

#/(other) ⇒ Object



369
370
371
372
373
374
# File 'Library/Homebrew/extend/pathname.rb', line 369

def /(other)
  if !other.respond_to?(:to_str) && !other.respond_to?(:to_path)
    odeprecated "Pathname#/ with #{other.class}", "a String or a Pathname"
  end
  join(other.to_s)
end

#append_lines(content, *open_args) ⇒ Object

Only appends to a file that is already created.



152
153
154
155
# File 'Library/Homebrew/extend/pathname.rb', line 152

def append_lines(content, *open_args)
  raise "Cannot append file that doesn't exist: #{self}" unless exist?
  open("a", *open_args) { |f| f.puts(content) }
end

#atomic_write(content) ⇒ Object

NOTE always overwrites



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'Library/Homebrew/extend/pathname.rb', line 170

def atomic_write(content)
  require "tempfile"
  tf = Tempfile.new(basename.to_s, dirname)
  begin
    tf.binmode
    tf.write(content)

    begin
      old_stat = stat
    rescue Errno::ENOENT
      old_stat = default_stat
    end

    uid = Process.uid
    gid = Process.groups.delete(old_stat.gid) { Process.gid }

    begin
      tf.chown(uid, gid)
      tf.chmod(old_stat.mode)
    rescue Errno::EPERM # rubocop:disable Lint/HandleExceptions
    end

    # Close the file before renaming to prevent the error: Device or resource busy
    # Affects primarily NFS.
    tf.close
    File.rename(tf.path, self)
  ensure
    tf.close!
  end
end

#binread(*open_args) ⇒ Object



164
165
166
# File 'Library/Homebrew/extend/pathname.rb', line 164

def binread(*open_args)
  open("rb", *open_args, &:read)
end

#binwrite(contents, *open_args) ⇒ Object



158
159
160
# File 'Library/Homebrew/extend/pathname.rb', line 158

def binwrite(contents, *open_args)
  open("wb", *open_args) { |f| f.write(contents) }
end

#cdObject



339
340
341
# File 'Library/Homebrew/extend/pathname.rb', line 339

def cd
  Dir.chdir(self) { yield self }
end

#ds_store?Boolean

Returns:

  • (Boolean)


461
462
463
# File 'Library/Homebrew/extend/pathname.rb', line 461

def ds_store?
  basename.to_s == ".DS_Store"
end

#env_script_all_files(dst, env) ⇒ Object

Writes a wrapper env script and moves all files to the dst



428
429
430
431
432
433
434
435
436
# File 'Library/Homebrew/extend/pathname.rb', line 428

def env_script_all_files(dst, env)
  dst.mkpath
  Pathname.glob("#{self}/*") do |file|
    next if file.directory?
    dst.install(file)
    new_file = dst.join(file.basename)
    file.write_env_script(new_file, env)
  end
end

#extname(path = to_s) ⇒ Object

extended to support common double extensions



231
232
233
234
235
236
237
# File 'Library/Homebrew/extend/pathname.rb', line 231

def extname(path = to_s)
  bottle_ext = path[BOTTLE_EXTNAME_RX, 1]
  return bottle_ext if bottle_ext
  archive_ext = path[/(\.(tar|cpio|pax)\.(gz|bz2|lz|xz|Z))$/, 1]
  return archive_ext if archive_ext
  File.extname(path)
end

#install(*sources) ⇒ Object

Moves a file from the original location to the Pathname's.



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'Library/Homebrew/extend/pathname.rb', line 70

def install(*sources)
  sources.each do |src|
    case src
    when Resource
      src.stage(self)
    when Resource::Partial
      src.resource.stage { install(*src.files) }
    when Array
      if src.empty?
        opoo "tried to install empty array to #{self}"
        break
      end
      src.each { |s| install_p(s, File.basename(s)) }
    when Hash
      if src.empty?
        opoo "tried to install empty hash to #{self}"
        break
      end
      src.each { |s, new_basename| install_p(s, new_basename) }
    else
      install_p(src, File.basename(src))
    end
  end
end

#install_metafiles(from = Pathname.pwd) ⇒ Object



447
448
449
450
451
452
453
454
455
456
457
458
459
# File 'Library/Homebrew/extend/pathname.rb', line 447

def install_metafiles(from = Pathname.pwd)
  Pathname(from).children.each do |p|
    next if p.directory?
    next unless Metafiles.copy?(p.basename.to_s)
    # Some software symlinks these files (see help2man.rb)
    filename = p.resolved_path
    # Some software links metafiles together, so by the time we iterate to one of them
    # we may have already moved it. libxml2's COPYING and Copyright are affected by this.
    next unless filename.exist?
    filename.chmod 0644
    install(filename)
  end
end

Creates symlinks to sources in this folder.



118
119
120
121
122
123
124
125
126
127
128
129
# File 'Library/Homebrew/extend/pathname.rb', line 118

def install_symlink(*sources)
  sources.each do |src|
    case src
    when Array
      src.each { |s| install_symlink_p(s, File.basename(s)) }
    when Hash
      src.each { |s, new_basename| install_symlink_p(s, new_basename) }
    else
      install_symlink_p(src, File.basename(src))
    end
  end
end

#sha256Object



326
327
328
329
# File 'Library/Homebrew/extend/pathname.rb', line 326

def sha256
  require "digest/sha2"
  incremental_hash(Digest::SHA256)
end

#stemObject

for filetypes we support, basename without extension



240
241
242
# File 'Library/Homebrew/extend/pathname.rb', line 240

def stem
  File.basename((path = to_s), extname(path))
end

#subdirsObject



343
344
345
# File 'Library/Homebrew/extend/pathname.rb', line 343

def subdirs
  children.select(&:directory?)
end

#verify_checksum(expected) ⇒ Object



331
332
333
334
335
# File 'Library/Homebrew/extend/pathname.rb', line 331

def verify_checksum(expected)
  raise ChecksumMissingError if expected.nil? || expected.empty?
  actual = Checksum.new(expected.hash_type, send(expected.hash_type).downcase)
  raise ChecksumMismatchError.new(self, expected, actual) unless expected == actual
end

#write(content, *open_args) ⇒ Object

we assume this pathname object is a file obviously



145
146
147
148
149
# File 'Library/Homebrew/extend/pathname.rb', line 145

def write(content, *open_args)
  raise "Will not overwrite #{self}" if exist?
  dirname.mkpath
  open("w", *open_args) { |f| f.write(content) }
end

#write_env_script(target, env) ⇒ Object

Writes an exec script that sets environment variables



417
418
419
420
421
422
423
424
425
# File 'Library/Homebrew/extend/pathname.rb', line 417

def write_env_script(target, env)
  env_export = ""
  env.each { |key, value| env_export += "#{key}=\"#{value}\" " }
  dirname.mkpath
  write <<~EOS
    #!/bin/bash
    #{env_export}exec "#{target}" "$@"
  EOS
end

#write_exec_script(*targets) ⇒ Object

Writes an exec script in this folder for each target pathname



400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
# File 'Library/Homebrew/extend/pathname.rb', line 400

def write_exec_script(*targets)
  targets.flatten!
  if targets.empty?
    opoo "tried to write exec scripts to #{self} for an empty list of targets"
    return
  end
  mkpath
  targets.each do |target|
    target = Pathname.new(target) # allow pathnames or strings
    join(target.basename).write <<~EOS
      #!/bin/bash
      exec "#{target}" "$@"
    EOS
  end
end

#write_jar_script(target_jar, script_name, java_opts = "") ⇒ Object

Writes an exec script that invokes a java jar



439
440
441
442
443
444
445
# File 'Library/Homebrew/extend/pathname.rb', line 439

def write_jar_script(target_jar, script_name, java_opts = "")
  mkpath
  join(script_name).write <<~EOS
    #!/bin/bash
    exec java #{java_opts} -jar #{target_jar} "$@"
  EOS
end