From a2894d48b9711ffa10553188959ee5a3d6d31eef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Sun, 5 Sep 2021 23:17:40 +0200 Subject: [PATCH] Initial conversion from shell script --- .editorconfig | 9 +++++++ .gitignore | 3 +++ README.md | 10 +++++++ TODO.md | 3 +++ cli.ts | 7 +++++ config/run.flags | 1 + deps.ts | 2 ++ doc/about.md | 6 +++++ doc/index | 1 + run | 19 ++++++++++++++ src/run.test.ts | 0 src/run.ts | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ tsconfig.json | 10 +++++++ 13 files changed, 139 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 README.md create mode 100644 TODO.md create mode 100755 cli.ts create mode 100644 config/run.flags create mode 100644 deps.ts create mode 100644 doc/about.md create mode 100644 doc/index create mode 100755 run create mode 100644 src/run.test.ts create mode 100644 src/run.ts create mode 100644 tsconfig.json diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..83c1115 --- /dev/null +++ b/.editorconfig @@ -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 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d69a4c0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +deno.d.ts +.vscode +.local diff --git a/README.md b/README.md new file mode 100644 index 0000000..601f844 --- /dev/null +++ b/README.md @@ -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. diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..b6642ac --- /dev/null +++ b/TODO.md @@ -0,0 +1,3 @@ +# TODO + +- Copy stderr/stdout to a log file diff --git a/cli.ts b/cli.ts new file mode 100755 index 0000000..6b5a570 --- /dev/null +++ b/cli.ts @@ -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()); +} diff --git a/config/run.flags b/config/run.flags new file mode 100644 index 0000000..8316014 --- /dev/null +++ b/config/run.flags @@ -0,0 +1 @@ +--allow-run=deno --allow-net=code.thunderk.net --allow-read=/tmp --allow-write=/tmp \ No newline at end of file diff --git a/deps.ts b/deps.ts new file mode 100644 index 0000000..d03c8c2 --- /dev/null +++ b/deps.ts @@ -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"; diff --git a/doc/about.md b/doc/about.md new file mode 100644 index 0000000..cfb118b --- /dev/null +++ b/doc/about.md @@ -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. diff --git a/doc/index b/doc/index new file mode 100644 index 0000000..93caaca --- /dev/null +++ b/doc/index @@ -0,0 +1 @@ +about \ No newline at end of file diff --git a/run b/run new file mode 100755 index 0000000..74d1c6d --- /dev/null +++ b/run @@ -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 diff --git a/src/run.test.ts b/src/run.test.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/run.ts b/src/run.ts new file mode 100644 index 0000000..3241d1e --- /dev/null +++ b/src/run.ts @@ -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 { + 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 { + 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); +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..e28737f --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "module": "esnext", + "target": "ESNext", + "strict": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "preserveConstEnums": true + } +}