@ecmaos/coreutils 0.1.5 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +45 -0
- package/dist/commands/basename.d.ts +4 -0
- package/dist/commands/basename.d.ts.map +1 -0
- package/dist/commands/basename.js +78 -0
- package/dist/commands/basename.js.map +1 -0
- package/dist/commands/cal.d.ts +4 -0
- package/dist/commands/cal.d.ts.map +1 -0
- package/dist/commands/cal.js +105 -0
- package/dist/commands/cal.js.map +1 -0
- package/dist/commands/cat.d.ts.map +1 -1
- package/dist/commands/cat.js +33 -25
- package/dist/commands/cat.js.map +1 -1
- package/dist/commands/cd.d.ts.map +1 -1
- package/dist/commands/cd.js +38 -10
- package/dist/commands/cd.js.map +1 -1
- package/dist/commands/chmod.d.ts.map +1 -1
- package/dist/commands/chmod.js +31 -9
- package/dist/commands/chmod.js.map +1 -1
- package/dist/commands/comm.d.ts +4 -0
- package/dist/commands/comm.d.ts.map +1 -0
- package/dist/commands/comm.js +162 -0
- package/dist/commands/comm.js.map +1 -0
- package/dist/commands/cp.d.ts.map +1 -1
- package/dist/commands/cp.js +61 -12
- package/dist/commands/cp.js.map +1 -1
- package/dist/commands/cut.d.ts +4 -0
- package/dist/commands/cut.d.ts.map +1 -0
- package/dist/commands/cut.js +208 -0
- package/dist/commands/cut.js.map +1 -0
- package/dist/commands/date.d.ts +4 -0
- package/dist/commands/date.d.ts.map +1 -0
- package/dist/commands/date.js +100 -0
- package/dist/commands/date.js.map +1 -0
- package/dist/commands/diff.d.ts +4 -0
- package/dist/commands/diff.d.ts.map +1 -0
- package/dist/commands/diff.js +194 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/dirname.d.ts +4 -0
- package/dist/commands/dirname.d.ts.map +1 -0
- package/dist/commands/dirname.js +50 -0
- package/dist/commands/dirname.js.map +1 -0
- package/dist/commands/echo.d.ts.map +1 -1
- package/dist/commands/echo.js +49 -10
- package/dist/commands/echo.js.map +1 -1
- package/dist/commands/false.d.ts +4 -0
- package/dist/commands/false.d.ts.map +1 -0
- package/dist/commands/false.js +27 -0
- package/dist/commands/false.js.map +1 -0
- package/dist/commands/find.d.ts +4 -0
- package/dist/commands/find.d.ts.map +1 -0
- package/dist/commands/find.js +181 -0
- package/dist/commands/find.js.map +1 -0
- package/dist/commands/grep.d.ts.map +1 -1
- package/dist/commands/grep.js +45 -10
- package/dist/commands/grep.js.map +1 -1
- package/dist/commands/head.d.ts.map +1 -1
- package/dist/commands/head.js +46 -9
- package/dist/commands/head.js.map +1 -1
- package/dist/commands/hex.d.ts.map +1 -1
- package/dist/commands/hex.js +16 -6
- package/dist/commands/hex.js.map +1 -1
- package/dist/commands/id.d.ts +4 -0
- package/dist/commands/id.d.ts.map +1 -0
- package/dist/commands/id.js +97 -0
- package/dist/commands/id.js.map +1 -0
- package/dist/commands/join.d.ts +4 -0
- package/dist/commands/join.d.ts.map +1 -0
- package/dist/commands/join.js +152 -0
- package/dist/commands/join.js.map +1 -0
- package/dist/commands/less.d.ts.map +1 -1
- package/dist/commands/less.js +16 -7
- package/dist/commands/less.js.map +1 -1
- package/dist/commands/ln.d.ts.map +1 -1
- package/dist/commands/ln.js +54 -12
- package/dist/commands/ln.js.map +1 -1
- package/dist/commands/ls.d.ts.map +1 -1
- package/dist/commands/ls.js +96 -91
- package/dist/commands/ls.js.map +1 -1
- package/dist/commands/mkdir.d.ts.map +1 -1
- package/dist/commands/mkdir.js +34 -9
- package/dist/commands/mkdir.js.map +1 -1
- package/dist/commands/mv.d.ts.map +1 -1
- package/dist/commands/mv.js +25 -7
- package/dist/commands/mv.js.map +1 -1
- package/dist/commands/nc.d.ts +4 -0
- package/dist/commands/nc.d.ts.map +1 -0
- package/dist/commands/nc.js +451 -0
- package/dist/commands/nc.js.map +1 -0
- package/dist/commands/nl.d.ts +4 -0
- package/dist/commands/nl.d.ts.map +1 -0
- package/dist/commands/nl.js +208 -0
- package/dist/commands/nl.js.map +1 -0
- package/dist/commands/passkey.d.ts.map +1 -1
- package/dist/commands/passkey.js +44 -18
- package/dist/commands/passkey.js.map +1 -1
- package/dist/commands/paste.d.ts +4 -0
- package/dist/commands/paste.d.ts.map +1 -0
- package/dist/commands/paste.js +161 -0
- package/dist/commands/paste.js.map +1 -0
- package/dist/commands/pwd.d.ts.map +1 -1
- package/dist/commands/pwd.js +13 -4
- package/dist/commands/pwd.js.map +1 -1
- package/dist/commands/rm.d.ts.map +1 -1
- package/dist/commands/rm.js +105 -12
- package/dist/commands/rm.js.map +1 -1
- package/dist/commands/rmdir.d.ts.map +1 -1
- package/dist/commands/rmdir.js +34 -9
- package/dist/commands/rmdir.js.map +1 -1
- package/dist/commands/sed.d.ts.map +1 -1
- package/dist/commands/sed.js +73 -28
- package/dist/commands/sed.js.map +1 -1
- package/dist/commands/seq.d.ts +4 -0
- package/dist/commands/seq.d.ts.map +1 -0
- package/dist/commands/seq.js +148 -0
- package/dist/commands/seq.js.map +1 -0
- package/dist/commands/sockets.d.ts +4 -0
- package/dist/commands/sockets.d.ts.map +1 -0
- package/dist/commands/sockets.js +239 -0
- package/dist/commands/sockets.js.map +1 -0
- package/dist/commands/sort.d.ts +4 -0
- package/dist/commands/sort.d.ts.map +1 -0
- package/dist/commands/sort.js +175 -0
- package/dist/commands/sort.js.map +1 -0
- package/dist/commands/split.d.ts +4 -0
- package/dist/commands/split.d.ts.map +1 -0
- package/dist/commands/split.js +147 -0
- package/dist/commands/split.js.map +1 -0
- package/dist/commands/stat.d.ts.map +1 -1
- package/dist/commands/stat.js +14 -6
- package/dist/commands/stat.js.map +1 -1
- package/dist/commands/tail.d.ts.map +1 -1
- package/dist/commands/tail.js +46 -9
- package/dist/commands/tail.js.map +1 -1
- package/dist/commands/tee.d.ts.map +1 -1
- package/dist/commands/tee.js +45 -10
- package/dist/commands/tee.js.map +1 -1
- package/dist/commands/test.d.ts +4 -0
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +99 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/commands/touch.d.ts.map +1 -1
- package/dist/commands/touch.js +34 -9
- package/dist/commands/touch.js.map +1 -1
- package/dist/commands/tr.d.ts +4 -0
- package/dist/commands/tr.d.ts.map +1 -0
- package/dist/commands/tr.js +162 -0
- package/dist/commands/tr.js.map +1 -0
- package/dist/commands/true.d.ts +4 -0
- package/dist/commands/true.d.ts.map +1 -0
- package/dist/commands/true.js +27 -0
- package/dist/commands/true.js.map +1 -0
- package/dist/commands/uniq.d.ts +4 -0
- package/dist/commands/uniq.d.ts.map +1 -0
- package/dist/commands/uniq.js +187 -0
- package/dist/commands/uniq.js.map +1 -0
- package/dist/commands/user.d.ts +4 -0
- package/dist/commands/user.d.ts.map +1 -0
- package/dist/commands/user.js +427 -0
- package/dist/commands/user.js.map +1 -0
- package/dist/commands/wc.d.ts +4 -0
- package/dist/commands/wc.d.ts.map +1 -0
- package/dist/commands/wc.js +178 -0
- package/dist/commands/wc.js.map +1 -0
- package/dist/commands/which.d.ts +4 -0
- package/dist/commands/which.d.ts.map +1 -0
- package/dist/commands/which.js +78 -0
- package/dist/commands/which.js.map +1 -0
- package/dist/commands/whoami.d.ts +4 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +28 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +67 -1
- package/dist/index.js.map +1 -1
- package/dist/shared/terminal-command.d.ts +8 -2
- package/dist/shared/terminal-command.d.ts.map +1 -1
- package/dist/shared/terminal-command.js +42 -17
- package/dist/shared/terminal-command.js.map +1 -1
- package/package.json +4 -2
- package/src/commands/basename.ts +84 -0
- package/src/commands/cal.ts +111 -0
- package/src/commands/cat.ts +37 -27
- package/src/commands/cd.ts +40 -12
- package/src/commands/chmod.ts +37 -11
- package/src/commands/comm.ts +169 -0
- package/src/commands/cp.ts +73 -15
- package/src/commands/cut.ts +214 -0
- package/src/commands/date.ts +97 -0
- package/src/commands/diff.ts +204 -0
- package/src/commands/dirname.ts +57 -0
- package/src/commands/echo.ts +51 -11
- package/src/commands/false.ts +31 -0
- package/src/commands/find.ts +184 -0
- package/src/commands/grep.ts +44 -11
- package/src/commands/head.ts +46 -10
- package/src/commands/hex.ts +19 -7
- package/src/commands/id.ts +94 -0
- package/src/commands/join.ts +162 -0
- package/src/commands/less.ts +20 -8
- package/src/commands/ln.ts +50 -13
- package/src/commands/ls.ts +110 -87
- package/src/commands/mkdir.ts +41 -12
- package/src/commands/mv.ts +31 -9
- package/src/commands/nc.ts +499 -0
- package/src/commands/nl.ts +201 -0
- package/src/commands/passkey.ts +46 -19
- package/src/commands/paste.ts +172 -0
- package/src/commands/pwd.ts +16 -4
- package/src/commands/rm.ts +118 -13
- package/src/commands/rmdir.ts +41 -12
- package/src/commands/sed.ts +64 -30
- package/src/commands/seq.ts +147 -0
- package/src/commands/sockets.ts +283 -0
- package/src/commands/sort.ts +175 -0
- package/src/commands/split.ts +154 -0
- package/src/commands/stat.ts +17 -8
- package/src/commands/tail.ts +46 -10
- package/src/commands/tee.ts +43 -11
- package/src/commands/test.ts +116 -0
- package/src/commands/touch.ts +41 -12
- package/src/commands/tr.ts +170 -0
- package/src/commands/true.ts +31 -0
- package/src/commands/uniq.ts +189 -0
- package/src/commands/user.ts +436 -0
- package/src/commands/wc.ts +181 -0
- package/src/commands/which.ts +89 -0
- package/src/commands/whoami.ts +32 -0
- package/src/index.ts +67 -1
- package/src/shared/terminal-command.ts +43 -16
package/src/commands/less.ts
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import path from 'path'
|
|
2
2
|
import ansi from 'ansi-escape-sequences'
|
|
3
|
-
import type { CommandLineOptions } from 'command-line-args'
|
|
4
3
|
import type { IDisposable } from '@xterm/xterm'
|
|
5
4
|
import type { Kernel, Process, Shell, Terminal } from '@ecmaos/types'
|
|
6
5
|
import { TerminalCommand } from '../shared/terminal-command.js'
|
|
7
6
|
import { writelnStderr } from '../shared/helpers.js'
|
|
8
7
|
|
|
8
|
+
function printUsage(process: Process | undefined, terminal: Terminal): void {
|
|
9
|
+
const usage = `Usage: less [OPTION]... FILE
|
|
10
|
+
View file contents interactively.
|
|
11
|
+
|
|
12
|
+
FILE the file to view (if omitted, reads from stdin)
|
|
13
|
+
--help display this help and exit`
|
|
14
|
+
writelnStderr(process, terminal, usage)
|
|
15
|
+
}
|
|
16
|
+
|
|
9
17
|
export function createCommand(kernel: Kernel, shell: Shell, terminal: Terminal): TerminalCommand {
|
|
10
18
|
return new TerminalCommand({
|
|
11
19
|
command: 'less',
|
|
@@ -13,21 +21,25 @@ export function createCommand(kernel: Kernel, shell: Shell, terminal: Terminal):
|
|
|
13
21
|
kernel,
|
|
14
22
|
shell,
|
|
15
23
|
terminal,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
],
|
|
20
|
-
run: async (argv: CommandLineOptions, process?: Process) => {
|
|
24
|
+
run: async (pid: number, argv: string[]) => {
|
|
25
|
+
const process = kernel.processes.get(pid) as Process | undefined
|
|
26
|
+
|
|
21
27
|
if (!process) return 1
|
|
22
28
|
|
|
29
|
+
if (argv.length > 0 && (argv[0] === '--help' || argv[0] === '-h')) {
|
|
30
|
+
printUsage(process, terminal)
|
|
31
|
+
return 0
|
|
32
|
+
}
|
|
33
|
+
|
|
23
34
|
let lines: string[] = []
|
|
24
35
|
let currentLine = 0
|
|
25
36
|
let keyListener: IDisposable | null = null
|
|
26
37
|
let linesRendered = 0
|
|
27
38
|
|
|
28
39
|
try {
|
|
29
|
-
|
|
30
|
-
|
|
40
|
+
const filePath = argv.length > 0 && argv[0] !== undefined && !argv[0].startsWith('-') ? argv[0] : undefined
|
|
41
|
+
|
|
42
|
+
if (filePath) {
|
|
31
43
|
const expandedPath = shell.expandTilde(filePath)
|
|
32
44
|
const fullPath = path.resolve(shell.cwd, expandedPath)
|
|
33
45
|
|
package/src/commands/ln.ts
CHANGED
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
import path from 'path'
|
|
2
2
|
import chalk from 'chalk'
|
|
3
|
-
import type { CommandLineOptions } from 'command-line-args'
|
|
4
3
|
import type { Kernel, Process, Shell, Terminal } from '@ecmaos/types'
|
|
5
4
|
import { TerminalCommand } from '../shared/terminal-command.js'
|
|
6
5
|
import { writelnStdout, writelnStderr } from '../shared/helpers.js'
|
|
7
6
|
|
|
7
|
+
function printUsage(process: Process | undefined, terminal: Terminal): void {
|
|
8
|
+
const usage = `Usage: ln [OPTION]... [-T] TARGET LINK_NAME
|
|
9
|
+
or: ln [OPTION]... TARGET
|
|
10
|
+
or: ln [OPTION]... TARGET... DIRECTORY
|
|
11
|
+
Create links between files.
|
|
12
|
+
|
|
13
|
+
-s, --symbolic make symbolic links instead of hard links
|
|
14
|
+
-f, --force remove existing destination files
|
|
15
|
+
-v, --verbose print name of each linked file
|
|
16
|
+
--help display this help and exit`
|
|
17
|
+
writelnStderr(process, terminal, usage)
|
|
18
|
+
}
|
|
19
|
+
|
|
8
20
|
export function createCommand(kernel: Kernel, shell: Shell, terminal: Terminal): TerminalCommand {
|
|
9
21
|
return new TerminalCommand({
|
|
10
22
|
command: 'ln',
|
|
@@ -12,18 +24,43 @@ export function createCommand(kernel: Kernel, shell: Shell, terminal: Terminal):
|
|
|
12
24
|
kernel,
|
|
13
25
|
shell,
|
|
14
26
|
terminal,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const args
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
run: async (pid: number, argv: string[]) => {
|
|
28
|
+
const process = kernel.processes.get(pid) as Process | undefined
|
|
29
|
+
|
|
30
|
+
if (argv.length > 0 && (argv[0] === '--help' || argv[0] === '-h')) {
|
|
31
|
+
printUsage(process, terminal)
|
|
32
|
+
return 0
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const args: string[] = []
|
|
36
|
+
let symbolic = false
|
|
37
|
+
let force = false
|
|
38
|
+
let verbose = false
|
|
39
|
+
|
|
40
|
+
for (const arg of argv) {
|
|
41
|
+
if (arg === '--help' || arg === '-h') {
|
|
42
|
+
printUsage(process, terminal)
|
|
43
|
+
return 0
|
|
44
|
+
} else if (arg === '-s' || arg === '--symbolic') {
|
|
45
|
+
symbolic = true
|
|
46
|
+
} else if (arg === '-f' || arg === '--force') {
|
|
47
|
+
force = true
|
|
48
|
+
} else if (arg === '-v' || arg === '--verbose') {
|
|
49
|
+
verbose = true
|
|
50
|
+
} else if (arg.startsWith('-')) {
|
|
51
|
+
const flags = arg.slice(1).split('')
|
|
52
|
+
if (flags.includes('s')) symbolic = true
|
|
53
|
+
if (flags.includes('f')) force = true
|
|
54
|
+
if (flags.includes('v')) verbose = true
|
|
55
|
+
const invalidFlags = flags.filter(f => !['s', 'f', 'v'].includes(f))
|
|
56
|
+
if (invalidFlags.length > 0) {
|
|
57
|
+
await writelnStderr(process, terminal, `ln: invalid option -- '${invalidFlags[0]}'`)
|
|
58
|
+
return 1
|
|
59
|
+
}
|
|
60
|
+
} else {
|
|
61
|
+
args.push(arg)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
27
64
|
|
|
28
65
|
if (args.length === 0) {
|
|
29
66
|
await writelnStderr(process, terminal, chalk.red('ln: missing file operand'))
|
package/src/commands/ls.ts
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import path from 'path'
|
|
2
2
|
import chalk from 'chalk'
|
|
3
|
+
import columnify from 'columnify'
|
|
3
4
|
import humanFormat from 'human-format'
|
|
4
|
-
import type { CommandLineOptions } from 'command-line-args'
|
|
5
5
|
import type { Kernel, Process, Shell, Terminal } from '@ecmaos/types'
|
|
6
6
|
import { TerminalCommand } from '../shared/terminal-command.js'
|
|
7
7
|
import { writelnStdout } from '../shared/helpers.js'
|
|
8
8
|
|
|
9
|
+
function printUsage(process: Process | undefined, terminal: Terminal): void {
|
|
10
|
+
const usage = `Usage: ls [OPTION]... [FILE]...
|
|
11
|
+
List information about the FILEs (the current directory by default).
|
|
12
|
+
|
|
13
|
+
--help display this help and exit`
|
|
14
|
+
writelnStdout(process, terminal, usage)
|
|
15
|
+
}
|
|
16
|
+
|
|
9
17
|
export function createCommand(kernel: Kernel, shell: Shell, terminal: Terminal): TerminalCommand {
|
|
10
18
|
return new TerminalCommand({
|
|
11
19
|
command: 'ls',
|
|
@@ -13,12 +21,15 @@ export function createCommand(kernel: Kernel, shell: Shell, terminal: Terminal):
|
|
|
13
21
|
kernel,
|
|
14
22
|
shell,
|
|
15
23
|
terminal,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
24
|
+
run: async (pid: number, argv: string[]) => {
|
|
25
|
+
const process = kernel.processes.get(pid) as Process | undefined
|
|
26
|
+
|
|
27
|
+
if (argv.length > 0 && (argv[0] === '--help' || argv[0] === '-h')) {
|
|
28
|
+
printUsage(process, terminal)
|
|
29
|
+
return 0
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const target = argv.length > 0 && argv[0] !== undefined && !argv[0].startsWith('-') ? argv[0] : shell.cwd
|
|
22
33
|
const fullPath = target ? path.resolve(shell.cwd, target === '' ? '.' : target) : shell.cwd
|
|
23
34
|
const stats = await shell.context.fs.promises.stat(fullPath)
|
|
24
35
|
const entries: string[] = stats.isDirectory() ? await shell.context.fs.promises.readdir(fullPath) : [fullPath]
|
|
@@ -143,91 +154,103 @@ export function createCommand(kernel: Kernel, shell: Shell, terminal: Terminal):
|
|
|
143
154
|
.filter((entry, index, self) => self.findIndex(e => e?.name === entry?.name) === index)
|
|
144
155
|
.filter((entry): entry is NonNullable<typeof entry> => entry !== null && entry !== undefined)
|
|
145
156
|
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
file.stats ? humanFormat(file.stats.size) : '',
|
|
181
|
-
file.stats ? getTimestampString(file.stats.mtime) : '',
|
|
182
|
-
modeString,
|
|
183
|
-
file.stats ? getOwnerString(file.stats) : '',
|
|
184
|
-
(() => {
|
|
185
|
-
const linkInfo = getLinkInfo(file.linkTarget, file.linkStats, file.stats)
|
|
186
|
-
if (linkInfo) return linkInfo
|
|
187
|
-
|
|
188
|
-
if (descriptions.has(path.resolve(fullPath, file.name))) return descriptions.get(path.resolve(fullPath, file.name))
|
|
189
|
-
if (file.name.includes('.')) {
|
|
190
|
-
const ext = file.name.split('.').pop()
|
|
191
|
-
if (ext && descriptions.has('.' + ext)) return descriptions.get('.' + ext)
|
|
192
|
-
}
|
|
193
|
-
if (!file.stats) return ''
|
|
194
|
-
if (file.stats.isBlockDevice() || file.stats.isCharacterDevice()) {
|
|
195
|
-
// TODO: zenfs `fs.mounts` is deprecated - use a better way of getting device info
|
|
196
|
-
}
|
|
157
|
+
const isDevDirectory = fullPath.startsWith('/dev')
|
|
158
|
+
const columns = isDevDirectory ? ['Name', 'Mode', 'Owner', 'Info'] : ['Name', 'Size', 'Modified', 'Mode', 'Owner', 'Info']
|
|
159
|
+
|
|
160
|
+
const directoryRows = directories.sort((a, b) => a.name.localeCompare(b.name)).map(directory => {
|
|
161
|
+
const displayName = directory.linkTarget
|
|
162
|
+
? `${directory.name} ${chalk.cyan('⟶')} ${directory.linkTarget}`
|
|
163
|
+
: directory.name
|
|
164
|
+
const modeStats = directory.linkStats && directory.linkStats.isSymbolicLink()
|
|
165
|
+
? directory.linkStats
|
|
166
|
+
: directory.stats
|
|
167
|
+
const modeString = modeStats
|
|
168
|
+
? getModeString(modeStats, directory.linkStats?.isSymbolicLink() ? directory.stats : undefined)
|
|
169
|
+
: ''
|
|
170
|
+
const linkInfo = getLinkInfo(directory.linkTarget, directory.linkStats, directory.stats)
|
|
171
|
+
|
|
172
|
+
const modeType = modeString?.charAt(0) || ''
|
|
173
|
+
const coloredName = modeType === 'd' ? chalk.blue(displayName)
|
|
174
|
+
: modeType === 'l' ? chalk.cyan(displayName)
|
|
175
|
+
: chalk.green(displayName)
|
|
176
|
+
|
|
177
|
+
const row: Record<string, string> = {
|
|
178
|
+
Name: coloredName,
|
|
179
|
+
Mode: chalk.gray(modeString),
|
|
180
|
+
Owner: directory.stats ? chalk.gray(getOwnerString(directory.stats)) : '',
|
|
181
|
+
Info: chalk.gray(linkInfo)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (!isDevDirectory) {
|
|
185
|
+
row.Size = ''
|
|
186
|
+
row.Modified = directory.stats ? chalk.gray(getTimestampString(directory.stats.mtime)) : ''
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return row
|
|
190
|
+
})
|
|
197
191
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
192
|
+
const fileRows = files.sort((a, b) => a.name.localeCompare(b.name)).map(file => {
|
|
193
|
+
const displayName = file.linkTarget
|
|
194
|
+
? `${file.name} ${chalk.cyan('⟶')} ${file.linkTarget}`
|
|
195
|
+
: file.name
|
|
196
|
+
const modeStats = file.linkStats && file.linkStats.isSymbolicLink()
|
|
197
|
+
? file.linkStats
|
|
198
|
+
: file.stats
|
|
199
|
+
const modeString = modeStats
|
|
200
|
+
? getModeString(modeStats, file.linkStats?.isSymbolicLink() ? file.stats : undefined)
|
|
201
|
+
: ''
|
|
202
|
+
|
|
203
|
+
const modeType = modeString?.charAt(0) || ''
|
|
204
|
+
const coloredName = modeType === 'd' ? chalk.blue(displayName)
|
|
205
|
+
: modeType === 'l' ? chalk.cyan(displayName)
|
|
206
|
+
: chalk.green(displayName)
|
|
207
|
+
|
|
208
|
+
const info = (() => {
|
|
209
|
+
const linkInfo = getLinkInfo(file.linkTarget, file.linkStats, file.stats)
|
|
210
|
+
if (linkInfo) return linkInfo
|
|
211
|
+
|
|
212
|
+
if (descriptions.has(path.resolve(fullPath, file.name))) return descriptions.get(path.resolve(fullPath, file.name)) || ''
|
|
213
|
+
if (file.name.includes('.')) {
|
|
214
|
+
const ext = file.name.split('.').pop()
|
|
215
|
+
if (ext && descriptions.has('.' + ext)) return descriptions.get('.' + ext) || ''
|
|
216
|
+
}
|
|
217
|
+
if (!file.stats) return ''
|
|
218
|
+
if (file.stats.isBlockDevice() || file.stats.isCharacterDevice()) {
|
|
219
|
+
// TODO: zenfs `fs.mounts` is deprecated - use a better way of getting device info
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return ''
|
|
223
|
+
})()
|
|
224
|
+
|
|
225
|
+
const row: Record<string, string> = {
|
|
226
|
+
Name: coloredName,
|
|
227
|
+
Mode: chalk.gray(modeString),
|
|
228
|
+
Owner: file.stats ? chalk.gray(getOwnerString(file.stats)) : '',
|
|
229
|
+
Info: chalk.gray(info)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (!isDevDirectory) {
|
|
233
|
+
row.Size = file.stats ? chalk.gray(humanFormat(file.stats.size)) : ''
|
|
234
|
+
row.Modified = file.stats ? chalk.gray(getTimestampString(file.stats.mtime)) : ''
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return row
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
const data = [...directoryRows, ...fileRows]
|
|
241
|
+
|
|
242
|
+
if (data.length > 0) {
|
|
243
|
+
const table = columnify(data, {
|
|
244
|
+
columns,
|
|
245
|
+
columnSplitter: ' ',
|
|
246
|
+
showHeaders: true,
|
|
247
|
+
headingTransform: (heading: string) => chalk.bold(heading)
|
|
201
248
|
})
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
// Special output for certain directories
|
|
205
|
-
if (fullPath.startsWith('/dev')) data.forEach(row => row.splice(1, 2)) // remove size and modified columns
|
|
206
|
-
|
|
207
|
-
const columnWidths = data[0]?.map((_, colIndex) => Math.max(...data.map(row => {
|
|
208
|
-
// Remove ANSI escape sequences before calculating length
|
|
209
|
-
const cleanedCell = row[colIndex]?.replace(/\u001b\[.*?m/g, '')
|
|
210
|
-
// count all emojis as two characters
|
|
211
|
-
return cleanedCell?.length || 0
|
|
212
|
-
})))
|
|
213
|
-
|
|
214
|
-
for (const [rowIndex, row] of data.entries()) {
|
|
215
|
-
const line = row
|
|
216
|
-
.map((cell, index) => {
|
|
217
|
-
const paddedCell = cell.padEnd(columnWidths?.[index] ?? 0)
|
|
218
|
-
if (index === 0 && rowIndex > 0) {
|
|
219
|
-
if (row[3]?.startsWith('d')) return chalk.blue(paddedCell)
|
|
220
|
-
else if (row[3]?.startsWith('l')) return chalk.cyan(paddedCell)
|
|
221
|
-
else return chalk.green(paddedCell)
|
|
222
|
-
} else return rowIndex === 0 ? chalk.bold(paddedCell) : chalk.gray(paddedCell)
|
|
223
|
-
})
|
|
224
|
-
.join(' ')
|
|
225
|
-
|
|
226
|
-
if (data.length > 1) await writelnStdout(process, terminal, line)
|
|
249
|
+
|
|
250
|
+
await writelnStdout(process, terminal, table)
|
|
227
251
|
}
|
|
228
252
|
|
|
229
253
|
return 0
|
|
230
254
|
}
|
|
231
255
|
})
|
|
232
256
|
}
|
|
233
|
-
|
package/src/commands/mkdir.ts
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import path from 'path'
|
|
2
|
-
import type {
|
|
3
|
-
import type { Kernel, Shell, Terminal } from '@ecmaos/types'
|
|
2
|
+
import type { Kernel, Process, Shell, Terminal } from '@ecmaos/types'
|
|
4
3
|
import { TerminalCommand } from '../shared/terminal-command.js'
|
|
4
|
+
import { writelnStdout, writelnStderr } from '../shared/helpers.js'
|
|
5
|
+
|
|
6
|
+
function printUsage(process: Process | undefined, terminal: Terminal): void {
|
|
7
|
+
const usage = `Usage: mkdir [OPTION]... DIRECTORY...
|
|
8
|
+
Create the DIRECTORY(ies), if they do not already exist.
|
|
9
|
+
|
|
10
|
+
--help display this help and exit`
|
|
11
|
+
writelnStdout(process, terminal, usage)
|
|
12
|
+
}
|
|
5
13
|
|
|
6
14
|
export function createCommand(kernel: Kernel, shell: Shell, terminal: Terminal): TerminalCommand {
|
|
7
15
|
return new TerminalCommand({
|
|
@@ -10,16 +18,37 @@ export function createCommand(kernel: Kernel, shell: Shell, terminal: Terminal):
|
|
|
10
18
|
kernel,
|
|
11
19
|
shell,
|
|
12
20
|
terminal,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
run: async (pid: number, argv: string[]) => {
|
|
22
|
+
const process = kernel.processes.get(pid) as Process | undefined
|
|
23
|
+
|
|
24
|
+
if (argv.length > 0 && (argv[0] === '--help' || argv[0] === '-h')) {
|
|
25
|
+
printUsage(process, terminal)
|
|
26
|
+
return 0
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (argv.length === 0) {
|
|
30
|
+
await writelnStderr(process, terminal, 'mkdir: missing operand')
|
|
31
|
+
await writelnStderr(process, terminal, "Try 'mkdir --help' for more information.")
|
|
32
|
+
return 1
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let hasError = false
|
|
36
|
+
|
|
37
|
+
for (const target of argv) {
|
|
38
|
+
if (!target || target.startsWith('-')) continue
|
|
39
|
+
|
|
40
|
+
const fullPath = target ? path.resolve(shell.cwd, target) : shell.cwd
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
await shell.context.fs.promises.mkdir(fullPath)
|
|
44
|
+
} catch (error) {
|
|
45
|
+
const errorMessage = error instanceof Error ? error.message : String(error)
|
|
46
|
+
await writelnStderr(process, terminal, `mkdir: ${target}: ${errorMessage}`)
|
|
47
|
+
hasError = true
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return hasError ? 1 : 0
|
|
22
52
|
}
|
|
23
53
|
})
|
|
24
54
|
}
|
|
25
|
-
|
package/src/commands/mv.ts
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import path from 'path'
|
|
2
2
|
import chalk from 'chalk'
|
|
3
|
-
import type { CommandLineOptions } from 'command-line-args'
|
|
4
3
|
import type { Kernel, Process, Shell, Terminal } from '@ecmaos/types'
|
|
5
4
|
import { TerminalCommand } from '../shared/terminal-command.js'
|
|
6
5
|
import { writelnStderr } from '../shared/helpers.js'
|
|
7
6
|
|
|
7
|
+
function printUsage(process: Process | undefined, terminal: Terminal): void {
|
|
8
|
+
const usage = `Usage: mv [OPTION]... SOURCE... DEST
|
|
9
|
+
Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.
|
|
10
|
+
|
|
11
|
+
--help display this help and exit`
|
|
12
|
+
writelnStderr(process, terminal, usage)
|
|
13
|
+
}
|
|
14
|
+
|
|
8
15
|
export function createCommand(kernel: Kernel, shell: Shell, terminal: Terminal): TerminalCommand {
|
|
9
16
|
return new TerminalCommand({
|
|
10
17
|
command: 'mv',
|
|
@@ -12,13 +19,29 @@ export function createCommand(kernel: Kernel, shell: Shell, terminal: Terminal):
|
|
|
12
19
|
kernel,
|
|
13
20
|
shell,
|
|
14
21
|
terminal,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
run: async (pid: number, argv: string[]) => {
|
|
23
|
+
const process = kernel.processes.get(pid) as Process | undefined
|
|
24
|
+
|
|
25
|
+
if (argv.length > 0 && (argv[0] === '--help' || argv[0] === '-h')) {
|
|
26
|
+
printUsage(process, terminal)
|
|
27
|
+
return 0
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const args: string[] = []
|
|
31
|
+
for (const arg of argv) {
|
|
32
|
+
if (arg && !arg.startsWith('-')) {
|
|
33
|
+
args.push(arg)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (args.length < 2) {
|
|
38
|
+
await writelnStderr(process, terminal, chalk.red('Usage: mv <source> <destination>'))
|
|
39
|
+
return 1
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const sourceInput = args[0]
|
|
43
|
+
const destinationInput = args[args.length - 1]
|
|
44
|
+
|
|
22
45
|
if (!sourceInput || !destinationInput) {
|
|
23
46
|
await writelnStderr(process, terminal, chalk.red('Usage: mv <source> <destination>'))
|
|
24
47
|
return 1
|
|
@@ -48,4 +71,3 @@ export function createCommand(kernel: Kernel, shell: Shell, terminal: Terminal):
|
|
|
48
71
|
}
|
|
49
72
|
})
|
|
50
73
|
}
|
|
51
|
-
|