Skip to content

Commit 06a608c

Browse files
committed
Implement ls in JavaScript
1 parent cb086a0 commit 06a608c

1 file changed

Lines changed: 74 additions & 0 deletions

File tree

  • implement-shell-tools/ls

‎implement-shell-tools/ls/ls.mjs‎

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import process from "node:process";
2+
import { promises as fs } from "node:fs";
3+
import { parseArgs } from "node:util";
4+
5+
const { values, positionals } = parseArgs({
6+
options: {
7+
one: { type: "boolean", short: "1", default: false },
8+
all: { type: "boolean", short: "a", default: false },
9+
},
10+
allowPositionals: true,
11+
});
12+
13+
const showAll = values.all;
14+
const paths = positionals.length > 0 ? positionals : ["."];
15+
16+
function stripPunctuation(name) {
17+
return name.replace(/[^\p{L}\p{N}]/gu, "");
18+
}
19+
20+
function compareNames(a, b) {
21+
const result = stripPunctuation(a).localeCompare(stripPunctuation(b));
22+
return result !== 0 ? result : a.localeCompare(b);
23+
}
24+
25+
const files = [];
26+
const directories = [];
27+
28+
for (const path of paths) {
29+
try {
30+
const stats = await fs.stat(path);
31+
if (stats.isDirectory()) {
32+
directories.push(path);
33+
} else {
34+
files.push(path);
35+
}
36+
} catch {
37+
console.error(`ls: cannot access '${path}': No such file or directory`);
38+
process.exitCode = 2;
39+
}
40+
}
41+
42+
files.sort(compareNames);
43+
directories.sort(compareNames);
44+
45+
const needHeaders = directories.length > 1 || files.length > 0;
46+
let printedSomething = false;
47+
48+
for (const file of files) {
49+
console.log(file);
50+
printedSomething = true;
51+
}
52+
53+
for (const dir of directories) {
54+
let entries = await fs.readdir(dir);
55+
56+
if (showAll) {
57+
entries = [".", "..", ...entries];
58+
} else {
59+
entries = entries.filter((entry) => !entry.startsWith("."));
60+
}
61+
entries.sort(compareNames);
62+
63+
if (needHeaders) {
64+
if (printedSomething) {
65+
console.log("");
66+
}
67+
console.log(`${dir}:`);
68+
}
69+
70+
for (const entry of entries) {
71+
console.log(entry);
72+
}
73+
printedSomething = true;
74+
}

0 commit comments

Comments
 (0)