File: index.js

package info (click to toggle)
node-findit2 2.2.3-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 116 kB
  • sloc: makefile: 4
file content (121 lines) | stat: -rw-r--r-- 3,077 bytes parent folder | download | duplicates (4)
1
2
3
4
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
var EventEmitter = require('events').EventEmitter;
var fs = require('fs');
var path = require('path');

module.exports = findit;

function findit(basedir, opts) {
  opts = opts || {};
  var followSymlinks = !!opts.followSymlinks;
  var myFs = opts.fs || fs;
  var emitter = new EventEmitter();
  var stopped = false;
  var pending = 0;
  var seen = {};

  emitter.stop = stop;
  walkPath(basedir);
  return emitter;

  function recursiveReadDir(basedir, linkPath) {
    pendStart();
    myFs.readdir(basedir, function(err, entries) {
      if (stopped) return;
      if (err) {
        handleError(err, basedir);
        pendEnd();
        return;
      }
      entries.forEach(function(entry) {
        var fullPath = path.join(basedir, entry);
        var fullLinkPath = linkPath && path.join(linkPath, entry);
        walkPath(fullPath, fullLinkPath);
      });
      pendEnd();
    });
  }

  function walkPath(fullPath, linkPath) {
    pendStart();
    myFs.lstat(fullPath, function(err, stats) {
      if (stopped) return;
      if (err) {
        handleError(err, fullPath);
        pendEnd();
        return;
      }
      emitter.emit('path', fullPath, stats, linkPath);
      var dirStopped = false;
      if (stats.isDirectory()) {
        if (seen[fullPath]) {
          err = new Error("file system loop detected");
          err.code = 'ELOOP';
          handleError(err, fullPath);
          pendEnd();
          return;
        }
        seen[fullPath] = true;

        emitter.emit('directory', fullPath, stats, stopDir, linkPath);
        if (!dirStopped) recursiveReadDir(fullPath, linkPath);
      } else if (stats.isFile()) {
        if (!seen[fullPath]) {
          seen[fullPath] = true;
          emitter.emit('file', fullPath, stats, linkPath);
        }
      } else if (stats.isSymbolicLink()) {
        emitter.emit('link', fullPath, stats, linkPath);
        if (followSymlinks) recursiveReadLink(fullPath);
      }
      pendEnd();

      function stopDir() {
        dirStopped = true;
      }
    });
  }

  function recursiveReadLink(linkPath) {
    pendStart();
    myFs.readlink(linkPath, function(err, linkString) {
      if (stopped) return;
      if (err) {
        handleError(err, linkPath);
        pendEnd();
        return;
      }
      var fullPath = path.resolve(path.dirname(linkPath), linkString);
      emitter.emit('readlink', linkPath, fullPath);
      walkPath(fullPath, linkPath);
      pendEnd();
    });
  }

  function stop() {
    if (stopped) return;
    stopped = true;
    emitter.emit('stop');
  }

  function handleError(err, errPath) {
    if (!err || stopped) return;
    err.path = errPath;
    emitter.emit('error', err);
  }

  function pendStart() {
    pending += 1;
  }

  function pendEnd() {
    if (stopped) return;
    pending -= 1;
    if (pending === 0) {
      emitter.emit('end');
    } else if (pending < 0) {
      // this should never happen; if this gets thrown we need to debug findit
      // and this stack trace will help.
      throw new Error("pendEnd called too many times");
    }
  }
}