<commit_before>require 'extend/pathname'

class Keg < Pathname
  def initialize path
    super path
    raise "#{to_s} is not a valid keg" unless parent.parent.realpath == HOMEBREW_CELLAR.realpath
    raise "#{to_s} is not a directory" unless directory?
  end

  # locale-specific directories have the form language[_territory][.codeset][@modifier]
  LOCALEDIR_RX = /(locale|man)\/([a-z]{2}|C|POSIX)(_[A-Z]{2})?(\.[a-zA-Z\-0-9]+(@.+)?)?/
  INFOFILE_RX = %r[info/([^.].*?\.info|dir)$]

  # if path is a file in a keg then this will return the containing Keg object
  def self.for path
    path = path.realpath
    while not path.root?
      return Keg.new(path) if path.parent.parent == HOMEBREW_CELLAR.realpath
      path = path.parent.realpath # realpath() prevents root? failing
    end
    raise NotAKegError, "#{path} is not inside a keg"
  end

  def uninstall
    rmtree
    parent.rmdir_if_possible
  end

  def unlink
    n=0

    %w[bin etc lib include sbin share var].map{ |d| self/d }.each do |src|
      next unless src.exist?
      src.find do |src|
        next if src == self
        dst=HOMEBREW_PREFIX+src.relative_path_from(self)

        # check whether the file to be unlinked is from the current keg first
        if !dst.symlink? || !dst.exist? || src != dst.resolved_path
          next
        end

        dst.uninstall_info if dst.to_s =~ INFOFILE_RX and ENV['HOMEBREW_KEEP_INFO']
        dst.unlink
        dst.parent.rmdir_if_possible
        n+=1
        Find.prune if src.directory?
      end
    end
    linked_keg_record.unlink if linked_keg_record.symlink?
    n
  end

  def fname
    parent.basename.to_s
  end

  def linked_keg_record
    @linked_keg_record ||= HOMEBREW_REPOSITORY/"Library/LinkedKegs"/fname
  end

  def linked?
    linked_keg_record.directory? and self == linked_keg_record.realpath
  end

  def completion_installed? shell
    dir = case shell
      when :bash then self/'etc/bash_completion.d'
      when :zsh then self/'share/zsh/site-functions'
      end
    return if dir.nil?
    dir.directory? and not dir.children.length.zero?
  end

  def version
    require 'version'
    Version.new(basename.to_s)
  end

  def basename
    Pathname.new(self.to_s).basename
  end

  def link mode=nil
    raise "Cannot link #{fname}\nAnother version is already linked: #{linked_keg_record.realpath}" if linked_keg_record.directory?

    # these are used by the ObserverPathnameExtension to count the number
    # of files and directories linked
    $n=0
    $d=0

    share_mkpaths=%w[aclocal doc info locale man]+(1..8).collect{|x|"man/man#{x}"}
    # cat pages are rare, but exist so the directories should be created
    share_mkpaths << (1..8).collect{ |x| "man/cat#{x}" }

    # yeah indeed, you have to force anything you need in the main tree into
    # these dirs REMEMBER that *NOT* everything needs to be in the main tree
    link_dir('etc', mode) {:mkpath}
    link_dir('bin', mode) {:skip_dir}
    link_dir('sbin', mode) {:skip_dir}
    link_dir('include', mode) {:link}

    link_dir('share', mode) do |path|
      case path.to_s
      when 'locale/locale.alias' then :skip_file
      when INFOFILE_RX then ENV['HOMEBREW_KEEP_INFO'] ? :info : :skip_file
      when LOCALEDIR_RX then :mkpath
      when *share_mkpaths then :mkpath
      when /^zsh/ then :mkpath
      else :link
      end
    end

    link_dir('lib', mode) do |path|
      case path.to_s
      when 'charset.alias' then :skip_file
      # pkg-config database gets explicitly created
      when 'pkgconfig' then :mkpath<commit_msg>Keg#unlink: use ObserverPathnameExtension<commit_after>require 'extend/pathname'

class Keg < Pathname
  def initialize path
    super path
    raise "#{to_s} is not a valid keg" unless parent.parent.realpath == HOMEBREW_CELLAR.realpath
    raise "#{to_s} is not a directory" unless directory?
  end

  # locale-specific directories have the form language[_territory][.codeset][@modifier]
  LOCALEDIR_RX = /(locale|man)\/([a-z]{2}|C|POSIX)(_[A-Z]{2})?(\.[a-zA-Z\-0-9]+(@.+)?)?/
  INFOFILE_RX = %r[info/([^.].*?\.info|dir)$]

  # if path is a file in a keg then this will return the containing Keg object
  def self.for path
    path = path.realpath
    while not path.root?
      return Keg.new(path) if path.parent.parent == HOMEBREW_CELLAR.realpath
      path = path.parent.realpath # realpath() prevents root? failing
    end
    raise NotAKegError, "#{path} is not inside a keg"
  end

  def uninstall
    rmtree
    parent.rmdir_if_possible
  end

  def unlink
    # these are used by the ObserverPathnameExtension to count the number
    # of files and directories linked
    $n=$d=0

    %w[bin etc lib include sbin share var].map{ |d| self/d }.each do |src|
      next unless src.exist?
      src.find do |src|
        next if src == self
        dst=HOMEBREW_PREFIX+src.relative_path_from(self)
        dst.extend ObserverPathnameExtension

        # check whether the file to be unlinked is from the current keg first
        if !dst.symlink? || !dst.exist? || src != dst.resolved_path
          next
        end

        dst.uninstall_info if dst.to_s =~ INFOFILE_RX and ENV['HOMEBREW_KEEP_INFO']
        dst.unlink
        dst.parent.rmdir_if_possible
        Find.prune if src.directory?
      end
    end
    linked_keg_record.unlink if linked_keg_record.symlink?
    $n+$d
  end

  def fname
    parent.basename.to_s
  end

  def linked_keg_record
    @linked_keg_record ||= HOMEBREW_REPOSITORY/"Library/LinkedKegs"/fname
  end

  def linked?
    linked_keg_record.directory? and self == linked_keg_record.realpath
  end

  def completion_installed? shell
    dir = case shell
      when :bash then self/'etc/bash_completion.d'
      when :zsh then self/'share/zsh/site-functions'
      end
    return if dir.nil?
    dir.directory? and not dir.children.length.zero?
  end

  def version
    require 'version'
    Version.new(basename.to_s)
  end

  def basename
    Pathname.new(self.to_s).basename
  end

  def link mode=nil
    raise "Cannot link #{fname}\nAnother version is already linked: #{linked_keg_record.realpath}" if linked_keg_record.directory?

    $n=0
    $d=0

    share_mkpaths=%w[aclocal doc info locale man]+(1..8).collect{|x|"man/man#{x}"}
    # cat pages are rare, but exist so the directories should be created
    share_mkpaths << (1..8).collect{ |x| "man/cat#{x}" }

    # yeah indeed, you have to force anything you need in the main tree into
    # these dirs REMEMBER that *NOT* everything needs to be in the main tree
    link_dir('etc', mode) {:mkpath}
    link_dir('bin', mode) {:skip_dir}
    link_dir('sbin', mode) {:skip_dir}
    link_dir('include', mode) {:link}

    link_dir('share', mode) do |path|
      case path.to_s
      when 'locale/locale.alias' then :skip_file
      when INFOFILE_RX then ENV['HOMEBREW_KEEP_INFO'] ? :info : :skip_file
      when LOCALEDIR_RX then :mkpath
      when *share_mkpaths then :mkpath
      when /^zsh/ then :mkpath
      else :link
      end
    end

    link_dir('lib', mode) do |path|
      case path.to_s
      when 'charset.alias' then :skip_file
      # pkg-config database gets explicitly created
      when 'pkgconfig' then :mkpath
{'fraction_non_alphanumeric': 0.10509465478841871, 'fraction_numerical': 0.0032015590200445434, 'mean_word_length': 2.9413055403181567, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3063888', 'n_tokens_mistral': 2508, 'n_tokens_neox': 2400, 'n_words': 694}