feat: improve bash-like command parsing

This commit is contained in:
binekrasik
2026-05-19 18:22:43 +02:00
parent b5f53473ed
commit 4a484dd546
8 changed files with 399 additions and 105 deletions

35
src/program/Cd.ts Normal file
View File

@@ -0,0 +1,35 @@
import { Item } from '../fs/Item'
import type { Shell } from '../shell/Shell'
import type { SimpleStream } from '../utils/SimpleStream'
import { Program } from './Program'
export class Cd extends Program {
private shell: Shell
constructor(shell: Shell) {
super()
this.shell = shell
}
async Exec(_: SimpleStream<string>, stdout: SimpleStream<string>, workdir: Item, args: string[]): Promise<number> {
const item = args[1]
? await Item.openDir(args[1].startsWith('/')
? args[1]
: `${workdir.GetPath()}${workdir.GetPath().endsWith('/') ? '' : '/'}${args[1]}`)
: workdir
if (args[1] && !item.IsDirectory()) {
stdout.emit("cd: error: the provided path is not a directory\n")
return 1
}
if (!(await item.Exists())) {
stdout.emit(`cd: error: path ${item.GetPath()} doesn't exist\n`)
return 2
}
await this.shell.SetWorkingDirectory(item)
return 0
}
}

View File

@@ -7,27 +7,29 @@ export class Echo extends Program {
super()
}
async Exec(_: SimpleStream<string>, stdout: SimpleStream<string>, workdir: Item, args: string[]): Promise<number> {
if (args.length < 2) {
stdout.emit("echo: error: missing path argument\n")
return 1
}
async Exec(_: SimpleStream<string>, stdout: SimpleStream<string>, __: Item, args: string[]): Promise<number> {
// if (args.length < 2) {
// stdout.emit("echo: error: missing path argument\n")
// return 1
// }
const item = await Item.open(args[1].startsWith('/')
? args[1]
: `${workdir.GetPath()}${workdir.GetPath().endsWith('/') ? '' : '/'}${args[1]}`)
// const item = await Item.open(args[1].startsWith('/')
// ? args[1]
// : `${workdir.GetPath()}${workdir.GetPath().endsWith('/') ? '' : '/'}${args[1]}`)
if (!(await item.Exists())) {
stdout.emit(`echo: error: item ${item.GetPath()} doesn't exist.\n`)
return 2
}
// if (!(await item.Exists())) {
// stdout.emit(`echo: error: item ${item.GetPath()} doesn't exist.\n`)
// return 2
// }
if (item.IsDirectory()) {
stdout.emit(`echo: error: can't write data to a directory; item ${item.GetPath()} is a directory.\n`)
return 3
}
// if (item.IsDirectory()) {
// stdout.emit(`echo: error: can't write data to a directory; item ${item.GetPath()} is a directory.\n`)
// return 3
// }
await item.Write(args.slice(2).join(' '))
// await item.Write(args.slice(2).join(' '))
stdout.emit(args.slice(1).join(' ') + '\n')
return 0
}

View File

@@ -24,14 +24,11 @@ export class Ls extends Program {
return 2
}
console.log(item)
stdout.emit(`-> Listing contents of item: '${item.GetPath()}'\n`)
stdout.emit(` [ drwx name ]\n`)
stdout.emit(` [ drwx name ]\n`)
const items = await item.List()
items.forEach(entry => {
stdout.emit(item.IsDirectory().toString())
stdout.emit(` | ${(item.IsDirectory() ? 'd' : '').padEnd(4, '-').padEnd(8, ' ')} ${entry.GetName()}\n`)
stdout.emit(` | ${`${(entry.IsDirectory() ? 'd' : '-')}${(entry.IsReadable() ? 'r' : '-')}${(entry.IsWritable() ? 'w' : '-')}${(entry.IsExecutable() ? 'x' : '-')}`.padEnd(8, ' ')} '${entry.GetName()}'\n`)
})
return 0

15
src/program/Printf.ts Normal file
View File

@@ -0,0 +1,15 @@
import { Item } from '../fs/Item'
import type { SimpleStream } from '../utils/SimpleStream'
import { Program } from './Program'
export class Printf extends Program {
constructor() {
super()
}
async Exec(_: SimpleStream<string>, stdout: SimpleStream<string>, __: Item, args: string[]): Promise<number> {
stdout.emit(args.slice(1).join(' '))
return 0
}
}

15
src/program/Pwd.ts Normal file
View File

@@ -0,0 +1,15 @@
import { Item } from '../fs/Item'
import type { SimpleStream } from '../utils/SimpleStream'
import { Program } from './Program'
export class Pwd extends Program {
constructor() {
super()
}
async Exec(_: SimpleStream<string>, stdout: SimpleStream<string>, workdir: Item, __: string[]): Promise<number> {
stdout.emit(`${workdir.GetPath()}\n`)
return 0
}
}