mirror of
https://github.com/Start9Labs/start-sdk.git
synced 2026-03-26 10:21:55 +00:00
chore: Add better sh
This commit is contained in:
39
lib/test/util.shell.test.ts
Normal file
39
lib/test/util.shell.test.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { sh } from "../util";
|
||||
|
||||
describe("Util shell values bluj ", () => {
|
||||
test("simple", () => {
|
||||
expect(sh("echo hello")).toEqual({ command: "echo", args: ["hello"] });
|
||||
}, 1);
|
||||
test("simple 2", () => {
|
||||
expect(sh("echo hello world")).toEqual({
|
||||
command: "echo",
|
||||
args: ["hello", "world"],
|
||||
});
|
||||
}, 1);
|
||||
test("simple A double quote", () => {
|
||||
expect(sh('echo "hello world" ')).toEqual({
|
||||
command: "echo",
|
||||
args: ["hello world"],
|
||||
});
|
||||
}, 1);
|
||||
test("simple A sing quote", () => {
|
||||
expect(sh("echo 'hello world' ")).toEqual({
|
||||
command: "echo",
|
||||
args: ["hello world"],
|
||||
});
|
||||
}, 1);
|
||||
test("simple complex", () => {
|
||||
expect(sh("echo arg1 'arg2 and' arg3 \"arg4 \" ")).toEqual({
|
||||
command: "echo",
|
||||
args: ["arg1", "arg2 and", "arg3", "arg4 "],
|
||||
});
|
||||
}, 1);
|
||||
test("nested", () => {
|
||||
expect(
|
||||
sh(`echo " 'arg1 ' " ' " arg2" ' arg4'"`)
|
||||
).toEqual({
|
||||
command: "echo",
|
||||
args: [` 'arg1 ' `, ` " arg2" `, `arg4'"`],
|
||||
});
|
||||
}, 1);
|
||||
});
|
||||
@@ -1,8 +1,57 @@
|
||||
import { Effects } from "../types";
|
||||
|
||||
const match =
|
||||
(regex: RegExp) =>
|
||||
(s: string): [string, string, string] => {
|
||||
const matched = s.match(regex);
|
||||
if (matched === null) {
|
||||
return [s, "", ""];
|
||||
}
|
||||
const [
|
||||
_all,
|
||||
_firstSet,
|
||||
notQuote,
|
||||
_maybeQuote,
|
||||
doubleQuoted,
|
||||
singleQuoted,
|
||||
rest,
|
||||
noQuotes,
|
||||
] = matched;
|
||||
const quoted = doubleQuoted || singleQuoted;
|
||||
if (!!noQuotes) {
|
||||
return [noQuotes || "", "", ""];
|
||||
}
|
||||
if (!notQuote && !quoted) {
|
||||
return [rest || "", "", ""];
|
||||
}
|
||||
return [notQuote || "", quoted || "", rest || ""];
|
||||
};
|
||||
const quotes = match(/^((.*?)("([^\"]*)"|'([^\']*)')(.*)|(.*))$/);
|
||||
const quoteSeperated = (s: string, quote: typeof quotes) => {
|
||||
const values = [];
|
||||
|
||||
let value = quote(s);
|
||||
while (true) {
|
||||
if (value[0].length) {
|
||||
values.push(...value[0].split(" "));
|
||||
}
|
||||
if (value[1].length) {
|
||||
values.push(value[1]);
|
||||
}
|
||||
if (!value[2].length) {
|
||||
break;
|
||||
}
|
||||
value = quote(value[2]);
|
||||
}
|
||||
return values;
|
||||
};
|
||||
|
||||
export function sh(shellCommand: string) {
|
||||
const [command, ...args] = quoteSeperated(shellCommand, quotes).filter(
|
||||
Boolean
|
||||
);
|
||||
return {
|
||||
command: "sh",
|
||||
args: ["-c", shellCommand],
|
||||
command,
|
||||
args,
|
||||
} satisfies Parameters<Effects["runCommand"]>[0];
|
||||
}
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "start-sdk",
|
||||
"version": "0.4.0-lib0.charlie7",
|
||||
"version": "0.4.0-lib0.charlie8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "start-sdk",
|
||||
"version": "0.4.0-lib0.charlie7",
|
||||
"version": "0.4.0-lib0.charlie8",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@iarna/toml": "^2.2.5",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "start-sdk",
|
||||
"version": "0.4.0-lib0.charlie7",
|
||||
"version": "0.4.0-lib0.charlie8",
|
||||
"description": "For making the patterns that are wanted in making services for the startOS.",
|
||||
"main": "./lib/index.js",
|
||||
"types": "./lib/index.d.ts",
|
||||
|
||||
Reference in New Issue
Block a user