forked from shelljs/shelljs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathls.js
142 lines (130 loc) · 4.31 KB
/
ls.js
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
var path = require('path');
var fs = require('fs');
var common = require('./common');
var glob = require('glob');
var globPatternRecursive = path.sep + '**';
common.register('ls', _ls, {
cmdOptions: {
'R': 'recursive',
'A': 'all',
'L': 'link',
'a': 'all_deprecated',
'd': 'directory',
'l': 'long',
},
});
//@
//@ ### ls([options,] [path, ...])
//@ ### ls([options,] path_array)
//@
//@ Available options:
//@
//@ + `-R`: recursive
//@ + `-A`: all files (include files beginning with `.`, except for `.` and `..`)
//@ + `-L`: follow symlinks
//@ + `-d`: list directories themselves, not their contents
//@ + `-l`: list objects representing each file, each with fields containing `ls
//@ -l` output fields. See
//@ [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats)
//@ for more info
//@
//@ Examples:
//@
//@ ```javascript
//@ ls('projs/*.js');
//@ ls('-R', '/users/me', '/tmp');
//@ ls('-R', ['/users/me', '/tmp']); // same as above
//@ ls('-l', 'file.txt'); // { name: 'file.txt', mode: 33188, nlink: 1, ...}
//@ ```
//@
//@ Returns a [ShellString](#shellstringstr) (with array-like properties) of all
//@ the files in the given `path`, or files in the current directory if no
//@ `path` is provided.
function _ls(options, paths) {
if (options.all_deprecated) {
// We won't support the -a option as it's hard to image why it's useful
// (it includes '.' and '..' in addition to '.*' files)
// For backwards compatibility we'll dump a deprecated message and proceed as before
common.log('ls: Option -a is deprecated. Use -A instead');
options.all = true;
}
if (!paths) {
paths = ['.'];
} else {
paths = [].slice.call(arguments, 1);
}
var list = [];
function pushFile(abs, relName, stat) {
if (process.platform === 'win32') {
relName = relName.replace(/\\/g, '/');
}
if (options.long) {
stat = stat || (options.link ? common.statFollowLinks(abs) : common.statNoFollowLinks(abs));
list.push(addLsAttributes(relName, stat));
} else {
// list.push(path.relative(rel || '.', file));
list.push(relName);
}
}
paths.forEach(function (p) {
var stat;
try {
stat = options.link ? common.statFollowLinks(p) : common.statNoFollowLinks(p);
// follow links to directories by default
if (stat.isSymbolicLink()) {
/* istanbul ignore next */
// workaround for https://github.com/shelljs/shelljs/issues/795
// codecov seems to have a bug that miscalculate this block as uncovered.
// but according to nyc report this block does get covered.
try {
var _stat = common.statFollowLinks(p);
if (_stat.isDirectory()) {
stat = _stat;
}
} catch (_) {} // bad symlink, treat it like a file
}
} catch (e) {
common.error('no such file or directory: ' + p, 2, { continue: true });
return;
}
// If the stat succeeded
if (stat.isDirectory() && !options.directory) {
if (options.recursive) {
// use glob, because it's simple
glob.sync(p + globPatternRecursive, { dot: options.all, follow: options.link })
.forEach(function (item) {
// Glob pattern returns the directory itself and needs to be filtered out.
if (path.relative(p, item)) {
pushFile(item, path.relative(p, item));
}
});
} else if (options.all) {
// use fs.readdirSync, because it's fast
fs.readdirSync(p).forEach(function (item) {
pushFile(path.join(p, item), item);
});
} else {
// use fs.readdirSync and then filter out secret files
fs.readdirSync(p).forEach(function (item) {
if (item[0] !== '.') {
pushFile(path.join(p, item), item);
}
});
}
} else {
pushFile(p, p, stat);
}
});
// Add methods, to make this more compatible with ShellStrings
return list;
}
function addLsAttributes(pathName, stats) {
// Note: this object will contain more information than .toString() returns
stats.name = pathName;
stats.toString = function () {
// Return a string resembling unix's `ls -l` format
return [this.mode, this.nlink, this.uid, this.gid, this.size, this.mtime, this.name].join(' ');
};
return stats;
}
module.exports = _ls;