chore: fix path syntax in core programs

This commit is contained in:
binekrasik
2026-05-19 23:19:36 +02:00
parent 1d00cf6deb
commit b5089251ff
9 changed files with 42 additions and 51 deletions

View File

@@ -15,7 +15,7 @@ export class Item {
private children: string[] = [] private children: string[] = []
private constructor(path: string) { private constructor(path: string) {
this.path = this.normalizePath(path) this.path = Item.NormalizePath(path)
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
@@ -222,7 +222,7 @@ export class Item {
return this.path return this.path
} }
private normalizePath(path: string): string { public static NormalizePath(path: string): string {
if (!path.startsWith('/')) path = '/' + path if (!path.startsWith('/')) path = '/' + path
// Resolve . and .. segments. // Resolve . and .. segments.
@@ -310,8 +310,6 @@ export class Item {
.get(this.storageKey) .get(this.storageKey)
request.onsuccess = () => { request.onsuccess = () => {
console.log(request.result)
const parsed = request.result as ItemPayload | undefined const parsed = request.result as ItemPayload | undefined
if (parsed) { if (parsed) {
this.isDirectory = parsed.isDirectory this.isDirectory = parsed.isDirectory
@@ -319,6 +317,7 @@ export class Item {
this.data = parsed.data this.data = parsed.data
this.children = parsed.children this.children = parsed.children
} }
resolve() resolve()
} }
request.onerror = () => reject(request.error) request.onerror = () => reject(request.error)

View File

@@ -3,21 +3,26 @@ import type { SimpleStream } from '../utils/SimpleStream'
import { Program } from './Program' import { Program } from './Program'
export class Cat extends Program { export class Cat extends Program {
async Exec(_: SimpleStream<string>, stdout: SimpleStream<string>, __: Item, args: string[]): Promise<number> { async Exec(_: SimpleStream<string>, stdout: SimpleStream<string>, workdir: Item, args: string[]): Promise<number> {
let item: Item = await Item.open(args[1]) if (args.length < 2) {
stdout.emit("cat: error: missing path argument\n")
return 1
}
const item = await Item.open(Item.NormalizePath(args[1].startsWith('/') ? args[1] : `${workdir.GetPath()}/${args[1]}`))
if (!(await item.Exists())) { if (!(await item.Exists())) {
stdout.emit(`cat: error: item ${item.GetPath()} doesn't exist.\n`) stdout.emit(`cat: error: item ${item.GetPath()} doesn't exist.\n`)
return 1 return 2
} }
if (item.IsDirectory()) { if (item.IsDirectory()) {
stdout.emit(`cat: error: can't read data from a directory; item ${item.GetPath()} is a directory.\n`) stdout.emit(`cat: error: can't read data from a directory; item ${item.GetPath()} is a directory.\n`)
return 2 return 3
} }
stdout.emit(`${item.ReadData()}`) stdout.emit(`${item.ReadData()}`)
stdout.emit('[ EOF ]\n') stdout.emit('<- EOF\n')
return 0 return 0
} }

View File

@@ -12,10 +12,14 @@ export class Cd extends Program {
} }
async Exec(_: SimpleStream<string>, stdout: SimpleStream<string>, workdir: Item, args: string[]): Promise<number> { async Exec(_: SimpleStream<string>, stdout: SimpleStream<string>, workdir: Item, args: string[]): Promise<number> {
// open the target directory, default to workdir
const item = args[1] const item = args[1]
? await Item.openDir(args[1].startsWith('/') ? await Item.openDir(Item.NormalizePath(
? args[1] args[1].startsWith('/')
: `${workdir.GetPath()}${workdir.GetPath().endsWith('/') ? '' : '/'}${args[1]}`) ? args[1]
: `${workdir.GetPath()}/${args[1]}`
))
: workdir : workdir
if (args[1] && !item.IsDirectory()) { if (args[1] && !item.IsDirectory()) {

View File

@@ -8,27 +8,6 @@ export class Echo extends Program {
} }
async Exec(_: SimpleStream<string>, stdout: SimpleStream<string>, __: Item, args: string[]): Promise<number> { 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]}`)
// 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
// }
// await item.Write(args.slice(2).join(' '))
stdout.emit(args.slice(1).join(' ') + '\n') stdout.emit(args.slice(1).join(' ') + '\n')
return 0 return 0

View File

@@ -8,10 +8,14 @@ export class Ls extends Program {
} }
async Exec(_: SimpleStream<string>, stdout: SimpleStream<string>, workdir: Item, args: string[]): Promise<number> { async Exec(_: SimpleStream<string>, stdout: SimpleStream<string>, workdir: Item, args: string[]): Promise<number> {
// open the target directory, default to workdir
const item = args[1] const item = args[1]
? await Item.openDir(args[1].startsWith('/') ? await Item.openDir(Item.NormalizePath(
? args[1] args[1].startsWith('/')
: `${workdir.GetPath()}${workdir.GetPath().endsWith('/') ? '' : '/'}${args[1]}`) ? args[1]
: `${workdir.GetPath()}/${args[1]}`
))
: workdir : workdir
if (args[1] && !item.IsDirectory()) { if (args[1] && !item.IsDirectory()) {
@@ -25,10 +29,10 @@ export class Ls extends Program {
} }
stdout.emit(`-> Listing contents of item: '${item.GetPath()}'\n`) stdout.emit(`-> Listing contents of item: '${item.GetPath()}'\n`)
stdout.emit(` [ drwx name ]\n`) stdout.emit(` [ drwx name ]\n`)
const items = await item.List() const items = await item.List()
items.forEach(entry => { items.forEach(entry => {
stdout.emit(` | ${`${(entry.IsDirectory() ? 'd' : '-')}${(entry.IsReadable() ? 'r' : '-')}${(entry.IsWritable() ? 'w' : '-')}${(entry.IsExecutable() ? 'x' : '-')}`.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 return 0

View File

@@ -13,11 +13,8 @@ export class Mkdir extends Program {
return 1 return 1
} }
const item = await Item.openDir(args[1].startsWith('/') const item = await Item.openDir(Item.NormalizePath(args[1].startsWith('/') ? args[1] : `${workdir.GetPath()}/${args[1]}`))
? args[1]
: `${workdir.GetPath()}${workdir.GetPath().endsWith('/') ? '' : '/'}${args[1]}`)
stdout.emit(`does ${args[1]} exist? ${await item.Exists()}\n`)
if (await item.Exists()) { if (await item.Exists()) {
stdout.emit(`mkdir: directory ${item.GetPath()} already exists.\n`) stdout.emit(`mkdir: directory ${item.GetPath()} already exists.\n`)

View File

@@ -30,7 +30,7 @@ export class Rm extends Program {
return 1 return 1
} }
stdout.emit(`removing: '${item.GetPath()}'\n`) stdout.emit(`-> removing: '${item.GetPath()}'\n`)
await item.Delete() await item.Delete()

View File

@@ -8,11 +8,12 @@ export class Touch extends Program {
} }
async Exec(_: SimpleStream<string>, stdout: SimpleStream<string>, workdir: Item, args: string[]): Promise<number> { async Exec(_: SimpleStream<string>, stdout: SimpleStream<string>, workdir: Item, args: string[]): Promise<number> {
stdout.emit(`touching children, please wait...\n`) if (args.length < 2) {
stdout.emit("touch: error: missing path argument\n")
return 1
}
const path = args.slice(1).join() const item = await Item.open(Item.NormalizePath(args[1].startsWith('/') ? args[1] : `${workdir.GetPath()}/${args[1]}`))
const item = await Item.open(path.includes('/') ? path : `${workdir.GetPath()}${workdir.GetPath().endsWith('/') ? '' : '/'}${path}`)
stdout.emit(`does ${item.GetPath()} exist? ${await item.Exists()}\n`)
if (await item.Exists()) { if (await item.Exists()) {
stdout.emit("touch: the file already exists.\n") stdout.emit("touch: the file already exists.\n")

View File

@@ -1,12 +1,14 @@
@use "colors.scss" as colors; @use "colors.scss" as colors;
#cursor { #cursor {
top: 0;
left: 0;
width: 1px; width: 1px;
height: 20px; height: 20px;
position: absolute;
background: colors.$terminal-white;
top: 0;
left: 0;
position: absolute;
backdrop-filter: invert(100%) saturate(0);
transition: .2s cubic-bezier(0, 1, 0.3, 1); transition: .2s cubic-bezier(0, 1, 0.3, 1);
} }