-
-
Notifications
You must be signed in to change notification settings - Fork 88
Expand file tree
/
Copy pathls.js
More file actions
90 lines (74 loc) · 2.81 KB
/
ls.js
File metadata and controls
90 lines (74 loc) · 2.81 KB
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
import { program } from "commander";
import { promises as fs } from "node:fs";
import process from "node:process";
// configure the CLI program with its name, description, arguments, options, and actions (the help instructions)
program
.name("ls")
.description("An alternative to the 'ls' command")
.argument("[directory]", "The directory to list")
// Commander stores -1 as a string key that is accessed using options['1']
.option("-1", "List all files, one per line")
.option("-a, --all", "Include hidden files (those starting with .) in the listing")
.action(async (directory, options) => {
try {
// default to current directory if none is specified
const dir = directory || ".";
await newLs(dir, options['1'], options.all);
} catch (err) {
console.error(`Error: ${err.message}`);
}
});
program.parse(process.argv);
// filter files based on visibility (includeHidden = true includes all files)
function filterFiles(entries, includeHidden) {
return entries.filter(name =>
includeHidden ? true : !name.startsWith(".")
);
}
// sort entries: directories first, then files,
function sortEntries(entries) {
const dirs = entries.filter(entry => {
try {
return fs.statSync(entry).isDirectory();
} catch (err) {
return false;
}
});
const files = entries.filter(entry => {
try {
return fs.statSync(entry).isFile();
} catch (err) {
return false;
}
});
// localeCompare = take into account rules of system language/region for ordering
// undefined = uses the system default, numeric = regular number sorting, base = ignore case & accents
return entries.sort((a, b) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" })
);
}
// print entries either one per line (-1 flag)
function printEntries(entries) {
entries.forEach(entry => console.log(entry));
}
async function newLs(directory, oneFlag, allFlag) {
try {
// check if path exists and determine if file or directory
const stats = await fs.stat(directory);
// if a file, just print the name
if (stats.isFile()) {
console.log(directory);
return;
}
// reads directory contents
const entries = await fs.readdir(directory);
// Filter out hidden files if no -a flag
const filteredEntries = filterFiles(entries, allFlag);
// Sort the entries using the sortEntries helper
const sortedEntries = sortEntries(filteredEntries);
// print entries for -1 flag (one per line)
printEntries(sortedEntries);
} catch (err) {
console.error(`ls: cannot access '${directory}': ${err.message}`);
}
}