mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-05-04 06:37:49 +02:00
Merge branch 'dev' into issues/2308
This commit is contained in:
@@ -26,7 +26,7 @@ export const TerminalHelpText: string[] = [
|
||||
" hostname Displays the hostname of the machine",
|
||||
" kill [script/pid] [args...] Stops the specified script on the current server ",
|
||||
" killall Stops all running scripts on the current machine",
|
||||
" ls [dir] [| grep pattern] Displays all files on the machine",
|
||||
" ls [dir] [--grep pattern] Displays all files on the machine",
|
||||
" lscpu Displays the number of CPU cores on the machine",
|
||||
" mem [script] [-t n] Displays the amount of RAM required to run the script",
|
||||
" mv [src] [dest] Move/rename a text or script file",
|
||||
@@ -295,28 +295,30 @@ export const HelpTexts: IMap<string[]> = {
|
||||
" ",
|
||||
],
|
||||
ls: [
|
||||
"Usage: ls [dir] [| grep pattern]",
|
||||
"Usage: ls [dir] [-l] [--grep pattern]",
|
||||
" ",
|
||||
"The ls command, with no arguments, prints all files and directories on the current server's directory to the Terminal screen. ",
|
||||
"The files will be displayed in alphabetical order. ",
|
||||
" ",
|
||||
"The 'dir' optional parameter can be used to display files/directories in another directory.",
|
||||
" ",
|
||||
"The '| grep pattern' optional parameter can be used to only display files whose filenames match the specified pattern.",
|
||||
"The '-l' optional parameter allows you to force each item onto a single line.",
|
||||
" ",
|
||||
"The '--grep pattern' optional parameter can be used to only display files whose filenames match the specified pattern.",
|
||||
" ",
|
||||
"Examples:",
|
||||
" ",
|
||||
"List all files with the '.script' extension in the current directory:",
|
||||
" ",
|
||||
" ls | grep .script",
|
||||
" ls -l --grep .script",
|
||||
" ",
|
||||
"List all files with the '.js' extension in the root directory:",
|
||||
" ",
|
||||
" ls / | grep .js",
|
||||
" ls / -l --grep .js",
|
||||
" ",
|
||||
"List all files with the word 'purchase' in the filename, in the 'scripts' directory:",
|
||||
" ",
|
||||
" ls scripts | grep purchase",
|
||||
" ls scripts -l --grep purchase",
|
||||
" ",
|
||||
],
|
||||
lscpu: ["Usage: lscpu", " ", "Prints the number of CPU Cores the current server has", " "],
|
||||
|
||||
@@ -8,6 +8,7 @@ import { BaseServer } from "../../Server/BaseServer";
|
||||
import { evaluateDirectoryPath, getFirstParentDirectory, isValidDirectoryPath } from "../DirectoryHelpers";
|
||||
import { IRouter } from "../../ui/Router";
|
||||
import { ITerminal } from "../ITerminal";
|
||||
import * as libarg from "arg"
|
||||
|
||||
export function ls(
|
||||
terminal: ITerminal,
|
||||
@@ -16,44 +17,46 @@ export function ls(
|
||||
server: BaseServer,
|
||||
args: (string | number | boolean)[],
|
||||
): void {
|
||||
let flags;
|
||||
try {
|
||||
flags = libarg({
|
||||
'-l': Boolean,
|
||||
'--grep': String,
|
||||
'-g': '--grep',
|
||||
},
|
||||
{ argv: args }
|
||||
)
|
||||
} catch (e) {
|
||||
// catch passing only -g / --grep with no string to use as the search
|
||||
incorrectUsage()
|
||||
return;
|
||||
}
|
||||
const filter = flags['--grep']
|
||||
|
||||
const numArgs = args.length;
|
||||
function incorrectUsage(): void {
|
||||
terminal.error("Incorrect usage of ls command. Usage: ls [dir] [| grep pattern]");
|
||||
terminal.error("Incorrect usage of ls command. Usage: ls [dir] [-l] [-g, --grep pattern]");
|
||||
}
|
||||
|
||||
if (numArgs > 4 || numArgs === 2) {
|
||||
if (numArgs > 4) {
|
||||
return incorrectUsage();
|
||||
}
|
||||
|
||||
// Grep
|
||||
let filter = ""; // Grep
|
||||
|
||||
// Directory path
|
||||
let prefix = terminal.cwd();
|
||||
if (!prefix.endsWith("/")) {
|
||||
prefix += "/";
|
||||
}
|
||||
|
||||
// If there are 3+ arguments, then the last 3 must be for grep
|
||||
if (numArgs >= 3) {
|
||||
if (args[numArgs - 2] !== "grep" || args[numArgs - 3] !== "|") {
|
||||
return incorrectUsage();
|
||||
}
|
||||
filter = args[numArgs - 1] + "";
|
||||
// If first arg doesn't contain a - it must be the file/folder
|
||||
const dir = (args[0] && typeof args[0] == "string" && !args[0].startsWith("-")) ? args[0] : ""
|
||||
const newPath = evaluateDirectoryPath(dir + "", terminal.cwd());
|
||||
prefix = newPath || "";
|
||||
if (!prefix.endsWith("/")) {
|
||||
prefix += "/";
|
||||
}
|
||||
|
||||
// If the second argument is not a pipe, then it must be for listing a directory
|
||||
if (numArgs >= 1 && args[0] !== "|") {
|
||||
const newPath = evaluateDirectoryPath(args[0] + "", terminal.cwd());
|
||||
prefix = newPath ? newPath : "";
|
||||
if (prefix != null) {
|
||||
if (!prefix.endsWith("/")) {
|
||||
prefix += "/";
|
||||
}
|
||||
if (!isValidDirectoryPath(prefix)) {
|
||||
return incorrectUsage();
|
||||
}
|
||||
}
|
||||
if (!isValidDirectoryPath(prefix)) {
|
||||
return incorrectUsage();
|
||||
}
|
||||
|
||||
// Root directory, which is the same as no 'prefix' at all
|
||||
@@ -139,10 +142,9 @@ export function ls(
|
||||
}),
|
||||
)();
|
||||
|
||||
const rowSplit = row
|
||||
.split(" ")
|
||||
.map((x) => x.trim())
|
||||
.filter((x) => !!x);
|
||||
const rowSplit = row.split("~");
|
||||
let rowSplitArray = rowSplit.map((x) => [x.trim(), x.replace(x.trim(), "")]);
|
||||
rowSplitArray = rowSplitArray.filter((x) => !!x[0]);
|
||||
|
||||
function onScriptLinkClick(filename: string): void {
|
||||
if (player.getCurrentServer().hostname !== hostname) {
|
||||
@@ -156,34 +158,42 @@ export function ls(
|
||||
|
||||
return (
|
||||
<span className={classes.scriptLinksWrap}>
|
||||
{rowSplit.map((rowItem) => (
|
||||
<span key={rowItem} className={classes.scriptLink} onClick={() => onScriptLinkClick(rowItem)}>
|
||||
{rowItem}
|
||||
{rowSplitArray.map((rowItem) => (
|
||||
<span>
|
||||
<span key={rowItem[0]} className={classes.scriptLink} onClick={() => onScriptLinkClick(rowItem[0])}>
|
||||
{rowItem[0]}
|
||||
</span>
|
||||
<span key={'s'+rowItem[0]}>
|
||||
{rowItem[1]}
|
||||
</span>
|
||||
</span>
|
||||
))}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
function postSegments(segments: string[], style?: any, linked?: boolean): void {
|
||||
function postSegments(segments: string[], flags: any, style?: any, linked?: boolean): void {
|
||||
const maxLength = Math.max(...segments.map((s) => s.length)) + 1;
|
||||
const filesPerRow = Math.ceil(80 / maxLength);
|
||||
const filesPerRow = flags["-l"] === true ? 1 : Math.ceil(80 / maxLength);
|
||||
for (let i = 0; i < segments.length; i++) {
|
||||
let row = "";
|
||||
for (let col = 0; col < filesPerRow; col++) {
|
||||
if (!(i < segments.length)) break;
|
||||
row += segments[i];
|
||||
row += " ".repeat(maxLength * (col + 1) - row.length);
|
||||
if(linked) {
|
||||
row += "~";
|
||||
}
|
||||
i++;
|
||||
}
|
||||
i--;
|
||||
if (!style) {
|
||||
terminal.print(row);
|
||||
} else if (linked) {
|
||||
terminal.printRaw(<ClickableScriptRow row={row} prefix={prefix} hostname={server.hostname} />);
|
||||
} else {
|
||||
terminal.printRaw(<span style={style}>{row}</span>);
|
||||
}
|
||||
terminal.printRaw(<ClickableScriptRow row={row} prefix={prefix} hostname={server.hostname} />);
|
||||
} else {
|
||||
terminal.printRaw(<span style={style}>{row}</span>);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,6 +206,6 @@ export function ls(
|
||||
{ segments: allScripts, style: { color: "yellow", fontStyle: "bold" }, linked: true },
|
||||
].filter((g) => g.segments.length > 0);
|
||||
for (let i = 0; i < groups.length; i++) {
|
||||
postSegments(groups[i].segments, groups[i].style, groups[i].linked);
|
||||
postSegments(groups[i].segments, flags, groups[i].style, groups[i].linked);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user