<commit_before>path = require 'path'

async = require 'async'
{Emitter} = require 'emissary'
fs = require 'fs-plus'

File = require './file'
PathWatcher = require './main'

# Public: Represents a directory on disk that can be watched for changes.
module.exports =
class Directory
  Emitter.includeInto(this)

  realPath: null

  # Public: Configures a new Directory instance, no files are accessed.
  #
  # path - A {String} containing the absolute path to the directory.
  # symlink - A {Boolean} indicating if the path is a symlink (default: false).
  constructor: (@path, @symlink=false) ->
    @on 'first-contents-changed-subscription-will-be-added', =>
      # Triggered by emissary, when a new contents-changed listener attaches
      @subscribeToNativeChangeEvents()

    @on 'last-contents-changed-subscription-removed', =>
      # Triggered by emissary, when the last contents-changed listener detaches
      @unsubscribeFromNativeChangeEvents()

    @lowerCasePath = @path.toLowerCase() if fs.isCaseInsensitive()

  # Public: Returns the {String} basename of the directory.
  getBaseName: ->
    path.basename(@path)

  # Public: Returns the directory's symbolic path.
  #
  # This may include unfollowed symlinks or relative directory entries. Or it
  # may be fully resolved, it depends on what you give it.
  getPath: -> @path

  # Public: Returns this directory's completely resolved path.
  #
  # All relative directory entries are removed and symlinks are resolved to
  # their final destination.
  getRealPathSync: ->
    unless @realPath?
      try
        @realPath = fs.realpathSync(@path)
        @lowerCaseRealPath = @realPath.toLowerCase() if fs.isCaseInsensitive()
      catch e
        @realPath = @path
        @lowerCaseRealPath = @lowerCasePath if fs.isCaseInsensitive()
    @realPath

  # Public: Returns whether the given path (real or symbolic) is inside this
  # directory.
  contains: (pathToCheck) ->
    return false unless pathToCheck

    # Normalize forward slashes to back slashes on windows
    fullPath = fullPath.replace(/\//g, '\\') if process.platform is 'win32'

    if fs.isCaseInsensitive()
      directoryPath = @lowerCasePath
      pathToCheck = pathToCheck.toLowerCase()
    else
      directoryPath = @path

    return true if @isPathPrefixOf(directoryPath, pathToCheck)

    # Check real path
    @getRealPathSync()
    if fs.isCaseInsensitive()
      directoryPath = @lowerCaseRealPath
    else
      directoryPath = @realPath

    @isPathPrefixOf(directoryPath, pathToCheck)

  # Public: Returns the relative path to the given path from this directory.
  relativize: (fullPath) ->
    return fullPath unless fullPath

    # Normalize forward slashes to back slashes on windows
    fullPath = fullPath.replace(/\//g, '\\') if process.platform is 'win32'
<commit_msg>Mention that exists isn't checked for<commit_after>path = require 'path'

async = require 'async'
{Emitter} = require 'emissary'
fs = require 'fs-plus'

File = require './file'
PathWatcher = require './main'

# Public: Represents a directory on disk that can be watched for changes.
module.exports =
class Directory
  Emitter.includeInto(this)

  realPath: null

  # Public: Configures a new Directory instance, no files are accessed.
  #
  # path - A {String} containing the absolute path to the directory.
  # symlink - A {Boolean} indicating if the path is a symlink (default: false).
  constructor: (@path, @symlink=false) ->
    @on 'first-contents-changed-subscription-will-be-added', =>
      # Triggered by emissary, when a new contents-changed listener attaches
      @subscribeToNativeChangeEvents()

    @on 'last-contents-changed-subscription-removed', =>
      # Triggered by emissary, when the last contents-changed listener detaches
      @unsubscribeFromNativeChangeEvents()

    @lowerCasePath = @path.toLowerCase() if fs.isCaseInsensitive()

  # Public: Returns the {String} basename of the directory.
  getBaseName: ->
    path.basename(@path)

  # Public: Returns the directory's symbolic path.
  #
  # This may include unfollowed symlinks or relative directory entries. Or it
  # may be fully resolved, it depends on what you give it.
  getPath: -> @path

  # Public: Returns this directory's completely resolved path.
  #
  # All relative directory entries are removed and symlinks are resolved to
  # their final destination.
  getRealPathSync: ->
    unless @realPath?
      try
        @realPath = fs.realpathSync(@path)
        @lowerCaseRealPath = @realPath.toLowerCase() if fs.isCaseInsensitive()
      catch e
        @realPath = @path
        @lowerCaseRealPath = @lowerCasePath if fs.isCaseInsensitive()
    @realPath

  # Public: Returns whether the given path (real or symbolic) is inside this
  # directory. This method does not actually check if the path exists, it just
  # checks if the path is under this directory.
  contains: (pathToCheck) ->
    return false unless pathToCheck

    # Normalize forward slashes to back slashes on windows
    fullPath = fullPath.replace(/\//g, '\\') if process.platform is 'win32'

    if fs.isCaseInsensitive()
      directoryPath = @lowerCasePath
      pathToCheck = pathToCheck.toLowerCase()
    else
      directoryPath = @path

    return true if @isPathPrefixOf(directoryPath, pathToCheck)

    # Check real path
    @getRealPathSync()
    if fs.isCaseInsensitive()
      directoryPath = @lowerCaseRealPath
    else
      directoryPath = @realPath

    @isPathPrefixOf(directoryPath, pathToCheck)

  # Public: Returns the relative path to the given path from this directory.
  relativize: (fullPath) ->
    return fullPath unless fullPath

    # Normalize forward slashes to back slashes on windows
    fullPath = fullPath.replace(/\//g, '\\') if process.platform is 'win32'

{'fraction_non_alphanumeric': 0.08867336335296155, 'fraction_numerical': 0.0013855213023900243, 'mean_word_length': 3.4560185185185186, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 19, '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': '1030607', 'n_tokens_mistral': 1650, 'n_tokens_neox': 1630, 'n_words': 567}