Initial conversion from shell script
This commit is contained in:
commit
a2894d48b9
9
.editorconfig
Normal file
9
.editorconfig
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*.{ts,json}]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
trim_trailing_whitespace = true
|
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
deno.d.ts
|
||||||
|
.vscode
|
||||||
|
.local
|
10
README.md
Normal file
10
README.md
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# typescript/run
|
||||||
|
|
||||||
|
[![Build Status](https://thunderk.visualstudio.com/typescript/_apis/build/status/run?branchName=master)](https://dev.azure.com/thunderk/typescript/_build?pipelineNameFilter=run)
|
||||||
|
|
||||||
|
## About
|
||||||
|
|
||||||
|
Utility to run command-line tools directly from Git hosting.
|
||||||
|
|
||||||
|
**Warning** - Currently, this is only compatible with
|
||||||
|
[code.thunderk.net](https://code.thunderk.net/) hosting.
|
7
cli.ts
Executable file
7
cli.ts
Executable file
|
@ -0,0 +1,7 @@
|
||||||
|
#!./run
|
||||||
|
import { Sys } from "./deps.ts";
|
||||||
|
import { run } from "./src/run.ts";
|
||||||
|
|
||||||
|
if (import.meta.main) {
|
||||||
|
await run(Sys.args.slice());
|
||||||
|
}
|
1
config/run.flags
Normal file
1
config/run.flags
Normal file
|
@ -0,0 +1 @@
|
||||||
|
--allow-run=deno --allow-net=code.thunderk.net --allow-read=/tmp --allow-write=/tmp
|
2
deps.ts
Normal file
2
deps.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export { Sys } from "https://js.thunderk.net/system@1.0.0/mod.ts";
|
||||||
|
export { difference } from "https://deno.land/std@0.106.0/datetime/mod.ts";
|
6
doc/about.md
Normal file
6
doc/about.md
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
## About
|
||||||
|
|
||||||
|
Utility to run command-line tools directly from Git hosting.
|
||||||
|
|
||||||
|
**Warning** - Currently, this is only compatible with
|
||||||
|
[code.thunderk.net](https://code.thunderk.net/) hosting.
|
19
run
Executable file
19
run
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Simplified run tool for deno commands
|
||||||
|
|
||||||
|
if test $# -eq 0
|
||||||
|
then
|
||||||
|
echo "Usage: $0 [file or command]"
|
||||||
|
exit 1
|
||||||
|
elif echo $1 | grep -q '.*.ts'
|
||||||
|
then
|
||||||
|
denocmd=run
|
||||||
|
denoargs=$1
|
||||||
|
shift
|
||||||
|
else
|
||||||
|
denocmd=$1
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
|
denoargs="$(cat config/$denocmd.flags 2> /dev/null) $denoargs $@"
|
||||||
|
exec deno $denocmd $denoargs
|
0
src/run.test.ts
Normal file
0
src/run.test.ts
Normal file
68
src/run.ts
Normal file
68
src/run.ts
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
import { difference, Sys } from "../deps.ts";
|
||||||
|
|
||||||
|
export class Runner {
|
||||||
|
constructor(readonly sys = Sys) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run a tool by its name and args
|
||||||
|
async run(args: string[]) {
|
||||||
|
const app = args.shift();
|
||||||
|
if (!app) {
|
||||||
|
throw new Error("Usage: run app [args...]");
|
||||||
|
}
|
||||||
|
|
||||||
|
const flags_txt = await this.downloadText(
|
||||||
|
`https://code.thunderk.net/typescript/${app}/raw/branch/master/config/run.flags`,
|
||||||
|
);
|
||||||
|
const flags = flags_txt.split(/\s+/).filter((arg) => arg);
|
||||||
|
if (flags.some((arg) => !arg.startsWith("--"))) {
|
||||||
|
throw new Error(`Bad run flags: ${flags}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!await this.checkStamp(app)) {
|
||||||
|
console.log("Reloading sources...");
|
||||||
|
flags.unshift("--reload");
|
||||||
|
}
|
||||||
|
|
||||||
|
const uri =
|
||||||
|
`https://code.thunderk.net/typescript/${app}/raw/branch/master/cli.ts`;
|
||||||
|
await this.sys.run({
|
||||||
|
cmd: ["deno", "run"].concat(flags).concat([uri]).concat(args),
|
||||||
|
}).status();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Download a remote text content (empty if not a 200 response)
|
||||||
|
async downloadText(uri: string): Promise<string> {
|
||||||
|
const response = await fetch(uri);
|
||||||
|
if (response.status == 200) {
|
||||||
|
const result = await response.text();
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check an app timestamp, returning true if it is valid
|
||||||
|
async checkStamp(app: string): Promise<boolean> {
|
||||||
|
const path = `/tmp/thunderk-run-${app}.stamp`;
|
||||||
|
try {
|
||||||
|
const stat = await this.sys.stat(path);
|
||||||
|
if (stat.isFile && stat.mtime) {
|
||||||
|
const age = difference(stat.mtime, new Date()).days ?? 0;
|
||||||
|
if (age < 1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.sys.writeTextFile(path, "");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run a remote program, by its name and args
|
||||||
|
export async function run(args: string[], sys = Sys) {
|
||||||
|
const runner = new Runner(sys);
|
||||||
|
await runner.run(args);
|
||||||
|
}
|
10
tsconfig.json
Normal file
10
tsconfig.json
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "esnext",
|
||||||
|
"target": "ESNext",
|
||||||
|
"strict": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"preserveConstEnums": true
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue