summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xmod.ts2
-rw-r--r--server/health.ts15
-rw-r--r--server/mod.ts2
-rw-r--r--u/fn/either.ts18
-rw-r--r--u/process/env.ts9
-rw-r--r--u/process/run.ts18
-rw-r--r--u/trace/itrace.ts2
-rw-r--r--u/trace/logger.ts51
-rw-r--r--worker/jobs/ci_pipeline.run4
-rwxr-xr-xworker/scripts/ansible_playbook2
10 files changed, 76 insertions, 47 deletions
diff --git a/mod.ts b/mod.ts
index 98470fc..b239992 100755
--- a/mod.ts
+++ b/mod.ts
@@ -1,4 +1,4 @@
-#!/usr/bin/env -S deno run --allow-env --allow-net
+#!/usr/bin/env -S deno run --allow-env --allow-net --allow-run
import { argv, IEither, Either } from "@emprespresso/pengueno";
import { runServer } from "@emprespresso/ci_server";
diff --git a/server/health.ts b/server/health.ts
index 8fbc69d..e69077b 100644
--- a/server/health.ts
+++ b/server/health.ts
@@ -17,9 +17,16 @@ export const healthCheck: HealthChecker = (
.bimap(TraceUtil.withFunctionTrace(healthCheck))
.move(getRequiredEnv("LAMINAR_HOST"))
// ensure LAMINAR_HOST is propagated to getStdout for other procedures
- .map((tEitherEnv) => tEitherEnv.get()
+ .map((tEitherEnv) =>
+ tEitherEnv
+ .get()
.flatMapAsync((_hasEnv) =>
- getStdout(tEitherEnv.move(["laminarc", "show-jobs"]))
- ))
- .map(TraceUtil.promiseify((stdout) => stdout.get().moveRight(HealthCheckOutput.YAASSSLAYQUEEN)))
+ getStdout(tEitherEnv.move(["laminarc", "show-jobs"])),
+ ),
+ )
+ .map(
+ TraceUtil.promiseify((stdout) =>
+ stdout.get().moveRight(HealthCheckOutput.YAASSSLAYQUEEN),
+ ),
+ )
.get();
diff --git a/server/mod.ts b/server/mod.ts
index 1fd4e99..02b307a 100644
--- a/server/mod.ts
+++ b/server/mod.ts
@@ -18,5 +18,5 @@ export const runServer = (
};
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));
};
diff --git a/u/fn/either.ts b/u/fn/either.ts
index 54f9fc2..ffe8033 100644
--- a/u/fn/either.ts
+++ b/u/fn/either.ts
@@ -32,7 +32,7 @@ export class Either<E, T> implements IEither<E, T> {
private readonly self: Left<E> | Right<T>;
private constructor(
- init: { err?: E, ok?: T },
+ init: { err?: E; ok?: T },
public readonly _tag: IEitherTag = iEitherTag,
) {
this.self = <Left<E> | Right<T>>{
@@ -85,11 +85,11 @@ export class Either<E, T> implements IEither<E, T> {
}
static left<E, T>(e: E): IEither<E, T> {
- return new Either<E, T>({ err: e});
+ return new Either<E, T>({ err: e });
}
static right<E, T>(t: T): IEither<E, T> {
- return new Either<E, T>({ok: t});
+ return new Either<E, T>({ ok: t });
}
static fromFailable<E, T>(s: Supplier<T>): IEither<E, T> {
@@ -100,12 +100,12 @@ export class Either<E, T> implements IEither<E, T> {
}
}
- static async fromFailableAsync<E, T>(s: Promise<T>): Promise<IEither<E, T>> {
- try {
- return Either.right<E, T>(await s);
- } catch (e) {
- return Either.left<E, T>(e as E);
- }
+ static async fromFailableAsync<E, T>(
+ s: Supplier<Promise<T>>,
+ ): Promise<IEither<E, T>> {
+ return await s()
+ .then((t: T) => Either.right<E, T>(t))
+ .catch((e: E) => Either.left<E, T>(e));
}
}
diff --git a/u/process/env.ts b/u/process/env.ts
index 470cb39..5ba4189 100644
--- a/u/process/env.ts
+++ b/u/process/env.ts
@@ -1,10 +1,13 @@
import { Either, type IEither } from "@emprespresso/pengueno";
export const getRequiredEnv = <V extends string>(name: V): IEither<Error, V> =>
- Either.fromFailable<Error, V | undefined>(() => Deno.env.get(name) as V | undefined) // could throw when no permission.
+ Either.fromFailable<Error, V | undefined>(
+ () => Deno.env.get(name) as V | undefined,
+ ) // could throw when no permission.
.flatMap(
- (v) => (v && Either.right(v)) ||
- Either.left(new Error(`environment variable "${name}" is required D:`))
+ (v) =>
+ (v && Either.right(v)) ||
+ Either.left(new Error(`environment variable "${name}" is required D:`)),
);
type ObjectFromList<T extends ReadonlyArray<string>, V = string> = {
diff --git a/u/process/run.ts b/u/process/run.ts
index 8004f75..7a74c3e 100644
--- a/u/process/run.ts
+++ b/u/process/run.ts
@@ -28,10 +28,12 @@ export const getStdout = <Trace>(
stdout: "piped",
stderr: "piped",
...options,
- }).output();
+ });
})
- .map((tOut) =>
- Either.fromFailableAsync<Error, Deno.CommandOutput>(tOut.get()),
+ .map((tCmd) =>
+ Either.fromFailableAsync<Error, Deno.CommandOutput>(() =>
+ tCmd.get().output(),
+ ),
)
.map(
TraceUtil.promiseify((tEitherOut) =>
@@ -45,11 +47,13 @@ export const getStdout = <Trace>(
tEitherOut.trace.addTrace(LogLevel.ERROR).trace(`o.o wat ${e}`);
return new Error(`${e}`);
})
- .flatMap((decodedOutput): Either<Error, string> => {
+ .flatMap((decodedOutput): IEither<Error, string> => {
const { code, stdoutText, stderrText } = decodedOutput;
- tEitherOut.trace
- .addTrace(LogLevel.DEBUG)
- .trace(`stderr hehehe ${stderrText}`);
+ if (stderrText) {
+ tEitherOut.trace
+ .addTrace(LogLevel.DEBUG)
+ .trace(`stderr: ${stderrText}`);
+ }
if (code !== 0) {
const msg = `i weceived an exit code of ${code} i wanna zewoooo :<`;
tEitherOut.trace.addTrace(LogLevel.ERROR).trace(msg);
diff --git a/u/trace/itrace.ts b/u/trace/itrace.ts
index c3cb8ad..fcfbe32 100644
--- a/u/trace/itrace.ts
+++ b/u/trace/itrace.ts
@@ -48,7 +48,7 @@ export class TraceableImpl<T, TraceWith> implements ITraceable<T, TraceWith> {
public flatMap<_T>(
mapper: ITraceableMapper<T, ITraceable<_T, TraceWith>, TraceWith>,
): ITraceable<_T, TraceWith> {
- return mapper(this);
+ return mapper(this);
}
public flatMapAsync<_T>(
diff --git a/u/trace/logger.ts b/u/trace/logger.ts
index 4f29839..8e62b02 100644
--- a/u/trace/logger.ts
+++ b/u/trace/logger.ts
@@ -11,6 +11,7 @@ export interface ILogger {
debug: (...args: unknown[]) => void;
warn: (...args: unknown[]) => void;
error: (...args: unknown[]) => void;
+ sys: (...args: unknown[]) => void;
}
export enum LogLevel {
UNKNOWN = "UNKNOWN",
@@ -18,6 +19,7 @@ export enum LogLevel {
WARN = "WARN",
DEBUG = "DEBUG",
ERROR = "ERROR",
+ SYS = "SYS",
}
const logLevelOrder: Array<LogLevel> = [
LogLevel.DEBUG,
@@ -35,6 +37,7 @@ const defaultAllowedLevels = () =>
LogLevel.INFO,
LogLevel.WARN,
LogLevel.ERROR,
+ LogLevel.SYS,
] as Array<LogLevel>;
export const logWithLevel = (
@@ -51,13 +54,21 @@ export const logWithLevel = (
return logger.warn;
case LogLevel.ERROR:
return logger.error;
+ case LogLevel.SYS:
+ return logger.sys;
}
};
export type LogTraceSupplier = ITraceWith<Supplier<string>>;
const defaultTrace = () => `[${new Date().toISOString()}]`;
-export const LoggerImpl = console;
+export const LoggerImpl = {
+ log: console.log,
+ debug: console.debug,
+ warn: console.warn,
+ error: console.error,
+ sys: console.log,
+};
export class LogTrace implements ITrace<LogTraceSupplier> {
constructor(
private readonly logger: ILogger = LoggerImpl,
@@ -78,28 +89,32 @@ export class LogTrace implements ITrace<LogTraceSupplier> {
}
public trace(trace: LogTraceSupplier) {
- const { line, level: _level } = this.foldTraces(this.traces.concat(trace));
+ const { traces, level: _level } = this.foldTraces(
+ this.traces.concat(trace),
+ );
if (!this.allowedLevels().includes(_level)) return;
const level = _level === LogLevel.UNKNOWN ? this.defaultLevel : _level;
- logWithLevel(this.logger, level)(`[${level}]${line}`);
+ const line = { level, message: traces.at(-1), traces: traces.slice(0, -1) };
+ logWithLevel(
+ this.logger,
+ level,
+ )(line);
}
- private foldTraces(traces: Array<LogTraceSupplier>) {
- const { line, level } = traces.reduce(
- (acc: { line: string; level: number }, t) => {
- const val = typeof t === "function" ? t() : t;
- if (isLogLevel(val)) {
- return {
- ...acc,
- level: Math.max(logLevelOrder.indexOf(val), acc.level),
- };
- }
- const line = [acc.line, val].join(" ");
- return { ...acc, line };
- },
- { line: "", level: -1 },
+ private foldTraces(_traces: Array<LogTraceSupplier>) {
+ const _logTraces = _traces.map((trace) =>
+ typeof trace === "function" ? trace() : trace,
);
- return { line, level: logLevelOrder[level] ?? LogLevel.UNKNOWN };
+ const _level = _logTraces
+ .filter((trace) => isLogLevel(trace))
+ .reduce((acc, level) => Math.max(logLevelOrder.indexOf(level), acc), -1);
+ const level = logLevelOrder[_level] ?? LogLevel.UNKNOWN;
+
+ const traces = _logTraces.filter((trace) => !isLogLevel(trace));
+ return {
+ level,
+ traces,
+ };
}
}
diff --git a/worker/jobs/ci_pipeline.run b/worker/jobs/ci_pipeline.run
index 46237f6..66b02ed 100644
--- a/worker/jobs/ci_pipeline.run
+++ b/worker/jobs/ci_pipeline.run
@@ -48,7 +48,7 @@ await LogMetricTraceable.ofLogTraceable(_logJob)
},
};
return Either.fromFailableAsync<Error, CheckoutCiJob>(
- Deno.mkdir(wd).then(() => Deno.chdir(wd))
+ () => Deno.mkdir(wd).then(() => Deno.chdir(wd))
.then(() => tEitherJob.move(fetchPackageJob).map(executeJob).get())
.then(() => ciJob),
);
@@ -58,7 +58,7 @@ await LogMetricTraceable.ofLogTraceable(_logJob)
tEitherCiJob.get().then((eitherCiJob) =>
eitherCiJob.flatMapAsync<{ cmd: Command; job: CheckoutCiJob }>((ciJob) =>
Either.fromFailableAsync<Error, string>(
- Deno.readTextFile(
+ () => Deno.readTextFile(
`${getSrcDirectoryForCiJob(ciJob)}/${CI_WORKFLOW_FILE}`,
),
).then((eitherWorkflowJson) =>
diff --git a/worker/scripts/ansible_playbook b/worker/scripts/ansible_playbook
index 026f892..fe2810b 100755
--- a/worker/scripts/ansible_playbook
+++ b/worker/scripts/ansible_playbook
@@ -104,7 +104,7 @@ await LogMetricTraceable.ofLogTraceable(_logJob).bimap(TraceUtil.withMetricTrace
const saveToTempFile = (text: string): Promise<IEither<Error, string>> =>
Either.fromFailableAsync(
- Deno.makeTempDir({ dir: Deno.cwd() })
+ () => Deno.makeTempDir({ dir: Deno.cwd() })
.then((dir) => Deno.makeTempFile({ dir }))
.then(async (f) => {
await Deno.writeTextFile(f, text);