public function find()

in src/filesystem/FileFinder.php [231:334]


  public function find() {

    $files = array();

    if (!is_dir($this->root) || !is_readable($this->root)) {
      throw new Exception(
        pht(
          "Invalid %s root directory specified ('%s'). Root directory ".
          "must be a directory, be readable, and be specified with an ".
          "absolute path.",
          __CLASS__,
          $this->root));
    }

    if ($this->forceMode == 'shell') {
      $php_mode = false;
    } else if ($this->forceMode == 'php') {
      $php_mode = true;
    } else {
      $php_mode = (phutil_is_windows() || !Filesystem::binaryExists('find'));
    }

    if ($php_mode) {
      $files = $this->getFiles('');
    } else {
      $args = array();
      $command = array();

      $command[] = 'find';
      if ($this->followSymlinks) {
        $command[] = '-L';
      }
      $command[] = '.';

      if ($this->exclude) {
        $command[] = $this->generateList('path', $this->exclude).' -prune';
        $command[] = '-o';
      }

      if ($this->type) {
        $command[] = '-type %s';
        $args[] = $this->type;
      }

      if ($this->name) {
        $command[] = $this->generateList('name', $this->name, 'name');
      }

      if ($this->suffix) {
        $command[] = $this->generateList('name', $this->suffix, 'suffix');
      }

      if ($this->paths) {
        $command[] = $this->generateList('path', $this->paths);
      }

      if ($this->nameGlobs) {
        $command[] = $this->generateList('name', $this->nameGlobs);
      }

      $command[] = '-print0';

      array_unshift($args, implode(' ', $command));
      list($stdout) = newv('ExecFuture', $args)
        ->setCWD($this->root)
        ->resolvex();

      $stdout = trim($stdout);
      if (!strlen($stdout)) {
        return array();
      }

      $files = explode("\0", $stdout);

      // On OSX/BSD, find prepends a './' to each file.
      foreach ($files as $key => $file) {
        // When matching directories, we can get "." back in the result set,
        // but this isn't an interesting result.
        if ($file == '.') {
          unset($files[$key]);
          continue;
        }

        if (substr($files[$key], 0, 2) == './') {
          $files[$key] = substr($files[$key], 2);
        }
      }
    }

    if (!$this->generateChecksums) {
      return $files;
    } else {
      $map = array();
      foreach ($files as $line) {
        $fullpath = $this->root.'/'.ltrim($line, '/');
        if (is_dir($fullpath)) {
          $map[$line] = null;
        } else {
          $map[$line] = md5_file($fullpath);
        }
      }
      return $map;
    }
  }