Featureful (#31)
* Fix loading within the CLI * Remove app * Remove promise handle * Add initial travis file * Add libxkbfile dependency * Add libxkbfile-dev * Add build script * Fix malformed bash statement * Remove yarn from script * Improve build script * Extract upx before usage * Only run upx if on linux * Ensure resource directory exists * Pack runnable binary * Export binary with platform * Improve build process * Install upx before running install script * Update typescript version before running nexe * Add os.release() function for multi-platform support * Update travis.yml to improve deployment * Add on CI * Update to v1.31.0 * Add libsecret * Update build target * Skip cleanup * Fix built-in extensions * Add basics for apps * Create custom DNS server * Fix forking within CLI. Fixes TS language features * Fix filename resolve * Fix default extensions path * Add custom dialog * Store workspace path * Remove outfiles * Cleanup * Always authed outside of CLI * Use location.host for client * Remove useless app interface * Remove debug file for building wordlist * Use chromes tcp host * Update patch * Build browser app before packaging * Replace all css containing file:// URLs, fix webviews * Fix save * Fix mkdir
This commit is contained in:
4
packages/runner/package.json
Normal file
4
packages/runner/package.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "@coder/runner",
|
||||
"main": "src/index.ts"
|
||||
}
|
1
packages/runner/src/index.ts
Normal file
1
packages/runner/src/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from "./runner";
|
114
packages/runner/src/runner.ts
Normal file
114
packages/runner/src/runner.ts
Normal file
@ -0,0 +1,114 @@
|
||||
import * as cp from "child_process";
|
||||
import { logger, Logger, field, time } from "@coder/logger";
|
||||
|
||||
export interface CommandResult {
|
||||
readonly exitCode: number;
|
||||
readonly stdout: string;
|
||||
readonly stderr: string;
|
||||
}
|
||||
|
||||
const execute = (command: string, args: string[] = [], options: cp.SpawnOptions, logger: Logger): Promise<CommandResult> => {
|
||||
let resolve: (result: CommandResult) => void;
|
||||
const prom = new Promise<CommandResult>(res => resolve = res);
|
||||
|
||||
const stdout: string[] = [];
|
||||
const stderr: string[] = [];
|
||||
const complete = (exitCode: number): void => {
|
||||
resolve({
|
||||
stderr: stderr.join(""),
|
||||
stdout: stdout.join(""),
|
||||
exitCode,
|
||||
});
|
||||
};
|
||||
logger.info(`Executing '${command} ${JSON.stringify(args)}'`, field("options", options));
|
||||
const proc = cp.spawn(command, args.length > 0 ? args : [], options);
|
||||
proc.on("close", (code) => {
|
||||
complete(code);
|
||||
});
|
||||
proc.on("exit", (code) => {
|
||||
complete(code!);
|
||||
});
|
||||
proc.stdout.on("data", (d) => {
|
||||
stdout.push(d.toString());
|
||||
logger.debug("stdio", field("stdout", d.toString()));
|
||||
});
|
||||
proc.stderr.on("data", (d) => {
|
||||
stderr.push(d.toString());
|
||||
logger.debug("stdio", field("stderr", d.toString()));
|
||||
});
|
||||
|
||||
return prom;
|
||||
};
|
||||
|
||||
export type TaskFunction = (runner: Runner) => void | Promise<void>;
|
||||
|
||||
export interface Runner {
|
||||
|
||||
cwd: string;
|
||||
execute(command: string, args?: string[], env?: object): Promise<CommandResult>;
|
||||
}
|
||||
|
||||
export interface Task {
|
||||
readonly name: string;
|
||||
readonly func: TaskFunction;
|
||||
}
|
||||
|
||||
const tasks = new Map<string, Task>();
|
||||
const activated = new Map<string, Promise<void>>();
|
||||
|
||||
export const register = (name: string, func: TaskFunction): () => void | Promise<void> => {
|
||||
if (tasks.has(name)) {
|
||||
throw new Error(`Task "${name}" already registered`);
|
||||
}
|
||||
|
||||
tasks.set(name, {
|
||||
name,
|
||||
func,
|
||||
});
|
||||
|
||||
return (): void | Promise<void> => {
|
||||
return run(name);
|
||||
};
|
||||
};
|
||||
|
||||
export const run = (name: string = process.argv[2]): void | Promise<void> => {
|
||||
const task = tasks.get(name);
|
||||
if (!task) {
|
||||
logger.error("Task not found.", field("name", name), field("available", Array.from(tasks.keys())));
|
||||
|
||||
return process.exit(1);
|
||||
}
|
||||
if (activated.has(name)) {
|
||||
return activated.get(name);
|
||||
}
|
||||
let cwd: string = process.cwd();
|
||||
const log = logger.named(name);
|
||||
const timer = time(Number.MAX_SAFE_INTEGER);
|
||||
log.info("Starting...");
|
||||
const prom = task.func({
|
||||
set cwd(path: string) {
|
||||
cwd = path;
|
||||
},
|
||||
execute(command: string, args: string[] = [], env?: object): Promise<CommandResult> {
|
||||
return execute(command, args, {
|
||||
cwd,
|
||||
env: env as NodeJS.ProcessEnv,
|
||||
}, log);
|
||||
},
|
||||
});
|
||||
|
||||
if (prom) {
|
||||
activated.set(name, prom);
|
||||
prom.then(() => {
|
||||
log.info("Completed!", field("time", timer));
|
||||
}).catch((ex) => {
|
||||
activated.delete(name);
|
||||
log.error(`Failed: ${ex.message}`);
|
||||
log.error(`Stack: ${ex.stack}`);
|
||||
|
||||
return process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
return prom;
|
||||
};
|
4
packages/runner/yarn.lock
Normal file
4
packages/runner/yarn.lock
Normal file
@ -0,0 +1,4 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
Reference in New Issue
Block a user