ls command almost finished, needed cleanup and rework of the code

This commit is contained in:
2025-12-09 04:57:54 +01:00
parent d0ff245582
commit 582eb68139
7 changed files with 108 additions and 39 deletions

View File

@@ -759,7 +759,7 @@
}, },
"22": { "22": {
"Inode": 22, "Inode": 22,
"Name": "Downloads", "Name": "Downloads Test",
"Type": 16384, "Type": 16384,
"Size": 4096, "Size": 4096,
"Children": [], "Children": [],

View File

@@ -1 +1 @@
32aac83d-ce2b-4def-977c-dcdcb6f514ed 32aac83d-ce2b-4def-977c-dcdcb6f514ef

View File

@@ -16,9 +16,9 @@ export type BashInitArgs = {
}; };
export type TimeStamps = { export type TimeStamps = {
mTime: Date; modified: Date;
cTime: Date; changed: Date;
aTime: Date; accessed: Date;
}; };
// TODO: Finish this // TODO: Finish this

View File

@@ -1,6 +1,6 @@
import { Bash, ExitCode, type Permission } from '../bash'; import { Bash, ExitCode, type Permission, type TimeStamps } from '../bash';
import { Type, type NodePerms, type TreeNode } from '../fs'; import { Type, type NodePerms, type TreeNode } from '../fs';
import { Sort } from '../sort'; import { Sort, SortNodeBy } from '../sort';
import type { CommandArgs, ICommand, Result, resultData } from '../static'; import type { CommandArgs, ICommand, Result, resultData } from '../static';
type LsEntry = { type LsEntry = {
@@ -42,11 +42,16 @@ export const cmd_ls = function (this: Bash, args: CommandArgs): Result {
const result: Result = { exitCode: ExitCode.ERROR, path: this.getCwd(), data: resultData }; const result: Result = { exitCode: ExitCode.ERROR, path: this.getCwd(), data: resultData };
const nodes: TreeNode[] = []; const nodes: TreeNode[] = [];
//Check if args contain any nonexistent flags, if so add it to an array and check its length. if 0 no bad flags //Check if any args contain the long flags with value and are valid flags inside the ls const
const invalidItems = args.flags.filter((flag) => !ls.flags.includes(flag)); const valuedArgs = args.flags.filter((flag: string) =>
console.log(invalidItems); flag.includes('=') && ls.flags.includes(flag.split('=')[0]));
console.log(valuedArgs);
if (invalidItems.length > 0) { //Check if args contain any nonexistent flags, if so add it to an array and check its length. if 0 no bad flags
const invalidArgs = args.flags.filter((flag) => !ls.flags.includes(flag) && !valuedArgs.includes(flag));
console.log(invalidArgs);
if (invalidArgs.length > 0) {
this.throwError(result); //No such flag/s this.throwError(result); //No such flag/s
} }
@@ -82,12 +87,20 @@ function result_ls(this: Bash, data: any, args: CommandArgs): HTMLElement {
const f_i: boolean = flagInfo.has('i') || flagInfo.has('inode'); const f_i: boolean = flagInfo.has('i') || flagInfo.has('inode');
const f_help: boolean = flagInfo.has('help'); const f_help: boolean = flagInfo.has('help');
const f_si: boolean = flagInfo.has('si'); const f_si: boolean = flagInfo.has('si');
const f_X: boolean = flagInfo.has('X');
const f_S: boolean = flagInfo.has('S');
const f_t: boolean = flagInfo.has('t');
const f_l: boolean = flagInfo.has('l'); const f_l: boolean = flagInfo.has('l');
const f_U: boolean = flagInfo.has('U'); const f_U: boolean = flagInfo.has('U');
const f_f: boolean = flagInfo.has('f'); const f_f: boolean = flagInfo.has('f');
const f_g: boolean = flagInfo.has('g'); const f_g: boolean = flagInfo.has('g');
const f_o: boolean = flagInfo.has('o'); const f_o: boolean = flagInfo.has('o');
let shouldShift: boolean = false
const valuedArgs = args.flags.filter((flag: string) =>
flag.includes('=') && ls.flags.includes(flag.split('=')[0]));
if (f_l || f_g || f_o) { if (f_l || f_g || f_o) {
const w: HTMLElement = document.createElement('div'); const w: HTMLElement = document.createElement('div');
@@ -96,9 +109,31 @@ function result_ls(this: Bash, data: any, args: CommandArgs): HTMLElement {
const children: TreeNode[] = node.children.map((child) => this.getFs().getNodeByINode(child)); const children: TreeNode[] = node.children.map((child) => this.getFs().getNodeByINode(child));
const rows: string[] = []; const rows: string[] = [];
const timeArg = valuedArgs.find((flag) => flag.startsWith('time'));
let timestamp: SortNodeBy.ATIME | SortNodeBy.CTIME | SortNodeBy.MTIME = SortNodeBy.MTIME;
if(timeArg) {
let value: string = timeArg.split('=')[1];
if (value && isValidNodeTimestamp(value)) {
timestamp = value;
console.log(timestamp);
}
}
if (!f_U && !f_f) { if (!f_U && !f_f) {
//TODO: Add sort by option later on const sortArg = valuedArgs.find((flag) => flag.startsWith('sort'));
Sort.nodeArraySort.call(this, children, f_r); let sortBy: SortNodeBy = SortNodeBy.NAME;
if(f_t) sortBy = timestamp;
if(f_S) sortBy = SortNodeBy.SIZE;
if(f_X) sortBy = SortNodeBy.EXTENSION;
if(sortArg) {
let value = sortArg.split('=')[1];
if(value && isValidNodeSortMethod(value)) {
sortBy = value;
console.log(sortBy, 'sortBy');
}
}
Sort.nodeArraySort.call(this, children, f_r, sortBy);
} }
const sizes = children.map((child) => child.size); const sizes = children.map((child) => child.size);
@@ -113,8 +148,8 @@ function result_ls(this: Bash, data: any, args: CommandArgs): HTMLElement {
children: formatChildren(child), children: formatChildren(child),
owners: formatOwners.call(this, child, flagInfo), owners: formatOwners.call(this, child, flagInfo),
size: formatSize.call(this, f_h, child, maxSizeWidth, f_si), size: formatSize.call(this, f_h, child, maxSizeWidth, f_si),
modt: formatModtime(child), modt: formatModtime(child, timestamp),
name: formatName(child, flagInfo) name: formatName(child, flagInfo, shouldShift)
}; };
if (f_i) cols.inode = child.inode; if (f_i) cols.inode = child.inode;
@@ -129,7 +164,7 @@ function result_ls(this: Bash, data: any, args: CommandArgs): HTMLElement {
children: formatChildren(node), children: formatChildren(node),
owners: formatOwners.call(this, node, flagInfo), owners: formatOwners.call(this, node, flagInfo),
size: formatSize.call(this, f_h, node, maxSizeWidth, f_si), size: formatSize.call(this, f_h, node, maxSizeWidth, f_si),
modt: formatModtime(node), modt: formatModtime(node, timestamp),
name: '.' name: '.'
}; };
let parent: LsEntry = { let parent: LsEntry = {
@@ -144,7 +179,7 @@ function result_ls(this: Bash, data: any, args: CommandArgs): HTMLElement {
children: formatChildren(parentNode), children: formatChildren(parentNode),
owners: formatOwners.call(this, parentNode, flagInfo), owners: formatOwners.call(this, parentNode, flagInfo),
size: formatSize.call(this, f_h, parentNode, maxSizeWidth, f_si), size: formatSize.call(this, f_h, parentNode, maxSizeWidth, f_si),
modt: formatModtime(parentNode), modt: formatModtime(parentNode, timestamp),
name: '..' name: '..'
}; };
} }
@@ -171,8 +206,19 @@ function result_ls(this: Bash, data: any, args: CommandArgs): HTMLElement {
rows.push('\n'); rows.push('\n');
} }
if(shouldShift) {
for(const row of rows) {
const name: string = row[row.length - 1];
if(!name.startsWith('"') || !name.startsWith("'"))
name.padStart(1, ' ');
else continue;
}
}
for (let i = 0; i < rows.length; i++) { for (let i = 0; i < rows.length; i++) {
const p: HTMLElement = document.createElement('p'); const p: HTMLElement = document.createElement('p');
p.innerText = rows[i]; p.innerText = rows[i];
elem.appendChild(p); elem.appendChild(p);
@@ -186,6 +232,14 @@ function result_ls(this: Bash, data: any, args: CommandArgs): HTMLElement {
return dummysonoerror; //TEMP SO NO ERROR CUZ RETURNS HTMLElement EVERY TIME, DELETE LATER return dummysonoerror; //TEMP SO NO ERROR CUZ RETURNS HTMLElement EVERY TIME, DELETE LATER
} }
function isValidNodeSortMethod(value: string): value is SortNodeBy {
return Object.values(SortNodeBy).includes(value as SortNodeBy);
}
function isValidNodeTimestamp(value: string): value is SortNodeBy.ATIME | SortNodeBy.CTIME | SortNodeBy.MTIME {
return Object.values(SortNodeBy).includes(value as SortNodeBy.ATIME | SortNodeBy.CTIME | SortNodeBy.MTIME);
}
function parsePerms(perms: NodePerms): string { function parsePerms(perms: NodePerms): string {
const parts: string[] = []; const parts: string[] = [];
//for each key (key representing key name and p representing the key contents) of entries in perms as types keyof NodePerms and Permission //for each key (key representing key name and p representing the key contents) of entries in perms as types keyof NodePerms and Permission
@@ -242,31 +296,32 @@ function formatSize(
return size.padStart(max, ' '); return size.padStart(max, ' ');
} }
function formatModtime(node: TreeNode): string { function formatModtime(node: TreeNode, sortBy: SortNodeBy.ATIME | SortNodeBy.CTIME | SortNodeBy.MTIME): string {
const now = new Date(); const now = new Date();
//TODO: Change this to be dynamic based on the --time value passed //TODO: Change this to be dynamic based on the --time value passed
const hours: string = node.timestamps.mTime.getHours().toString().padStart(2, '0'); const hours: string = node.timestamps[sortBy].getHours().toString().padStart(2, '0');
const minutes: string = node.timestamps.mTime.getMinutes().toString().padStart(2, '0'); const minutes: string = node.timestamps[sortBy].getMinutes().toString().padStart(2, '0');
const time: string = const time: string =
now.getFullYear() === node.timestamps.mTime.getFullYear() now.getFullYear() === node.timestamps[sortBy].getFullYear()
? `${hours}:${minutes}` ? `${hours}:${minutes}`
: node.timestamps.mTime.getFullYear().toString(); : node.timestamps[sortBy].getFullYear().toString();
return [ return [
months[node.timestamps.mTime.getMonth()], months[node.timestamps[sortBy].getMonth()],
node.timestamps.mTime.getDate().toString().padStart(2, ' '), node.timestamps[sortBy].getDate().toString().padStart(2, ' '),
`${time}` `${time}`
].join(' '); ].join(' ');
} }
function formatName(node: TreeNode, flag: any) { function formatName(node: TreeNode, flag: any, shouldShift: boolean) {
let name: string; let name: string;
const char: string = flag.has('Q') ? '"' : "'"; const char: string = flag.has('Q') ? '"' : "'";
if (flag.has('N')) { if (/\s/.test(node.name)) {
name = node.name; name = `${char}${node.name}${char}`
shouldShift = true;
} else { } else {
name = /\s/.test(node.name) ? `${char}${node.name}${char}` : `${node.name}`; //test if any spaces specifically '\s' (escape and 's' for space) name = `${node.name}`;
} }
return flag.has('p') && node.type === Type.Directory ? `${name}/` : name; return flag.has('p') && node.type === Type.Directory ? `${name}/` : name;

View File

@@ -0,0 +1,13 @@
import type { ICommand } from "../static"
import { cmd_ls } from "./ls"
type LsEntry
export class ls {
public const ls: ICommand = {
method: ls.cmd_ls
}
}

View File

@@ -2,14 +2,14 @@ import type { TreeNode } from './fs';
import type { Bash } from './bash'; import type { Bash } from './bash';
export enum SortNodeBy { export enum SortNodeBy {
NAME, NAME = 'name',
INODE, INODE = 'inode',
SIZE, SIZE = 'size',
EXTENSION, EXTENSION = 'extension',
TYPE, TYPE = 'type',
MTIME = 'mTime', MTIME = 'modified',
ATIME = 'aTime', ATIME = 'accessed',
CTIME = 'cTime' CTIME = 'changed'
} }
export class Sort { export class Sort {
@@ -100,6 +100,7 @@ export class Sort {
case SortNodeBy.MTIME: case SortNodeBy.MTIME:
case SortNodeBy.ATIME: case SortNodeBy.ATIME:
case SortNodeBy.CTIME: { case SortNodeBy.CTIME: {
console.log(sortBy, 'sortby');
// The sortBy serves as the lookup key in the timestamps object. // The sortBy serves as the lookup key in the timestamps object.
// It works because the times in SortBy enum have assigned values matching the names of the keys in the TreeNode object // It works because the times in SortBy enum have assigned values matching the names of the keys in the TreeNode object
const timeA: number = a.timestamps[sortBy].getTime(); const timeA: number = a.timestamps[sortBy].getTime();

View File

@@ -44,9 +44,9 @@ function jsonToNodeTable(data: any, parent?: number): Map<number, TreeNode> {
owner: object.Owner, owner: object.Owner,
group: object.Group, group: object.Group,
timestamps: { timestamps: {
mTime: new Date(object.TimeStamps.MTime), modified: new Date(object.TimeStamps.MTime),
cTime: new Date(object.TimeStamps.CTime), changed: new Date(object.TimeStamps.CTime),
aTime: new Date(object.TimeStamps.ATime) accessed: new Date(object.TimeStamps.ATime)
}, },
parent: object.Parent parent: object.Parent
}; };