diff options
-rwxr-xr-x | mod.ts | 21 | ||||
-rw-r--r-- | server/mod.ts | 4 | ||||
-rw-r--r-- | u/process/argv.ts | 118 | ||||
-rw-r--r-- | u/process/run.ts | 2 | ||||
-rw-r--r-- | u/trace/logger.ts | 6 |
5 files changed, 78 insertions, 73 deletions
@@ -3,25 +3,24 @@ import { argv, IEither, Either } from "@emprespresso/pengueno"; import { runServer } from "@emprespresso/ci_server"; -const _defaults = { - "--port": "9000", - "--host": "0.0.0.0", -}; const main = ( _argv = Deno.args, - defaults = _defaults, -): Promise<IEither<Error, void>> => - argv(["--run-server", "--port", "--host"], defaults, _argv) +): Promise<IEither<Error, 0>> => + argv(["--run-server", "--port", "--host"], { + "--run-server": { absent: false, unspecified: true, present: () => true }, + "--port": { absent: 9000, present: (port) => parseInt(port) }, + "--host": { absent: "0.0.0.0", present: (host) => host }, + }, _argv) .mapRight((args) => ({ - server_mode: "--run-server" in args, - port: parseInt(args["--port"]), - host: args["--host"], + server_mode: args["--run-server"], + port: args["--port"], + host: args["--host"], })) .flatMapAsync((runConfig) => { if (runConfig.server_mode) { return runServer(runConfig.port, runConfig.host); } - return Promise.resolve(Either.right(undefined)); + return Promise.resolve(Either.right(0)); }); if (import.meta.main) { diff --git a/server/mod.ts b/server/mod.ts index 02b307a..1d168d2 100644 --- a/server/mod.ts +++ b/server/mod.ts @@ -11,12 +11,12 @@ const server = new CiHookServer(); export const runServer = ( port: number, host: string, -): Promise<IEither<Error, void>> => { +): Promise<IEither<Error, 0>> => { const serverConfig = { host, port, }; return Either.fromFailable<Error, Deno.HttpServer>(() => Deno.serve(serverConfig, (req) => server.serve(req)), - ).flatMapAsync((server) => Either.fromFailableAsync(() => server.finished)); + ).flatMapAsync((server) => Either.fromFailableAsync(() => server.finished.then(() => 0))); }; diff --git a/u/process/argv.ts b/u/process/argv.ts index 8e85477..45f8ff0 100644 --- a/u/process/argv.ts +++ b/u/process/argv.ts @@ -1,66 +1,72 @@ -import { Either, type IEither } from "@emprespresso/pengueno"; +import { Either, type Mapper, type IEither } from "@emprespresso/pengueno"; export const isArgKey = <K extends string>(k: string): k is K => k.startsWith("--"); -export const getArg = <K extends string, V extends string>( +interface ArgHandler<V> { + absent?: V; + unspecified?: V; + present: Mapper<string, V>; +} + +export const getArg = <K extends string, V>( arg: K, - args: Array<K>, + argv: Array<string>, + whenValue: ArgHandler<V>, ): IEither<Error, V> => { - const result = args.findIndex((_arg) => _arg.startsWith(arg)); - if (result < 0) return Either.left(new Error("no argument found for " + arg)); - const [resultArg, next]: Array<string | undefined> = [ - args[result], - args.at(result + 1), - ]; - if (resultArg && resultArg.includes("=")) { - return Either.right(resultArg.split("=")[1] as V); - } - if (typeof next === "undefined") - return Either.left(new Error("no value specified for " + arg)); - if (isArgKey(next)) - return Either.left( - new Error("next value for arg " + arg + " is another arg " + next), - ); - return Either.right(next as V); + const value = argv.filter((_argv) => isArgKey(_argv) && _argv.split("=")[0] === arg).map((_argv, i) => { + const next = _argv.includes("=") ? _argv.split("=")[1] : argv.at(i + 1); + if (next) { + if (isArgKey(next)) return whenValue.unspecified; + return whenValue.present(next); + } + return whenValue.unspecified; + }).find(x => x) ?? whenValue.absent; + if (value === undefined) { + return Either.left(new Error("no value specified for " + arg)); + } + return Either.right(value); }; -type ObjectFromList<T extends ReadonlyArray<string>, V = string> = { - [K in T extends ReadonlyArray<infer U> ? U : never]: V; +type MappedArgs< + Args extends ReadonlyArray<string>, + Handlers extends Partial<Record<Args[number], ArgHandler<unknown>>> +> = { + [K in Args[number]]: K extends keyof Handlers + ? Handlers[K] extends ArgHandler<infer T> + ? T + : string + : string; }; -export const argv = <K extends string, V extends string>( - args: ReadonlyArray<K>, - defaultArgs?: Partial<Record<K, V>>, - argv = Deno.args, -) => { - return args - .map((arg) => [arg, getArg(arg, argv)] as [K, IEither<Error, V>]) - .map(([arg, specified]): [K, IEither<Error, V>] => [ - arg, - specified.fold(({ isLeft, isRight, value }): IEither<Error, V> => { - if (isRight) { - return Either.right(value); - } - const hasDefaultVal = isLeft && defaultArgs && arg in defaultArgs; - if (hasDefaultVal) { - return Either.right(defaultArgs[arg]!); - } - return Either.left(value); - }), - ]) - .reduce( - ( - acc: IEither<Error, ObjectFromList<typeof args, V>>, - x: [K, IEither<Error, V>], - ): IEither<Error, ObjectFromList<typeof args, V>> => { - const [arg, eitherVal] = x; - return acc.flatMap((args) => { - return eitherVal.mapRight((envValue) => ({ - ...args, - [arg]: envValue, - })); - }); - }, - Either.right({} as ObjectFromList<typeof args, V>), - ); + +export const argv = < + const Args extends ReadonlyArray<string>, + const Handlers extends Partial<Record<Args[number], ArgHandler<unknown>>> +>( + args: Args, + handlers?: Handlers, + argv = Deno.args, +): IEither<Error, MappedArgs<Args, Handlers>> => { + type Result = MappedArgs<Args, Handlers>; + + const defaultHandler: ArgHandler<string> = { present: (value: string) => value }; + + const processArg = (arg: Args[number]): IEither<Error, [Args[number], unknown]> => { + const handler = handlers?.[arg] ?? defaultHandler; + return getArg(arg, argv, handler).mapRight(value => [arg, value] as const); + }; + + const argResults = args.map(processArg); + + return argResults.reduce( + (acc: IEither<Error, Partial<Result>>, current: IEither<Error, readonly [Args[number], unknown]>) => { + return acc.flatMap(accValue => + current.mapRight(([key, value]) => ({ + ...accValue, + [key]: value + })) + ); + }, + Either.right({} as Partial<Result>) + ).mapRight(result => result as Result); }; diff --git a/u/process/run.ts b/u/process/run.ts index b09e64e..abe143c 100644 --- a/u/process/run.ts +++ b/u/process/run.ts @@ -22,7 +22,7 @@ export const getStdout = ( .bimap(TraceUtil.withFunctionTrace(getStdout)) .map((tCmd) => { const cmd = tCmd.get(); - tCmd.trace.trace(`:> im gonna run this command! ${cmd}`); + tCmd.trace.trace(`Command = ${cmd} :> im gonna run this command! `); const [exec, ...args] = typeof cmd === "string" ? cmd.split(" ") : cmd; return new Deno.Command(exec, { args, diff --git a/u/trace/logger.ts b/u/trace/logger.ts index 29cabd4..d8392eb 100644 --- a/u/trace/logger.ts +++ b/u/trace/logger.ts @@ -93,11 +93,11 @@ export interface ILogger { class LoggerImpl implements ILogger { private readonly textEncoder = new TextEncoder(); - public log(level: LogLevel, ...msg: string[]) { + public log(level: LogLevel, ...trace: string[]) { const message = JSON.stringify({ level, - msg, - }, null, 2); + trace, + }, null, 4); const styled = `${this.getStyle(level)}${message}${ANSI.RESET}\n`; this.getStream(level).writeSync(this.textEncoder.encode(styled)); } |