import { debug } from "../../deno_ral/log.ts";
import { normalizePath } from "../path.ts";
import { copy } from "io/copy";
import { writeAll } from "io/write-all";
Deno.realPathSync = normalizePath;
(Deno as any).copy = copy;
(Deno as any).writeAll = writeAll;
const maxAttempts = 5;
function withAttempts<T>(callable: () => T) {
for (let i = 0; i < maxAttempts; i++) {
try {
return callable();
} catch (err) {
if (!(err instanceof Error)) {
throw err;
}
if (err.message) {
debug("Error attempting to create temp file: " + err.message);
if (i === maxAttempts - 1) {
throw err;
} else {
debug(`Retrying... ${i + 1} of ${maxAttempts - 1}`);
}
}
}
}
throw new Error("Shouldn't get here");
}
function withAttemptsAsync<T>(callable: () => Promise<T>) {
const inner = (attempt: number): Promise<T> => {
return callable().catch((err) => {
if (!(err instanceof Error)) {
throw err;
}
if (err.message) {
debug("Error attempting to create temp file: " + err.message);
}
if (attempt === maxAttempts - 1) {
throw err;
} else {
debug(`Retrying... ${attempt + 1} of ${maxAttempts - 1}`);
return inner(attempt + 1);
}
});
};
return inner(0);
}
const oldMakeTempFile: typeof Deno.makeTempFile = Deno.makeTempFile;
const oldMakeTempFileSync: typeof Deno.makeTempFileSync = Deno.makeTempFileSync;
const oldMakeTempDir: typeof Deno.makeTempDir = Deno.makeTempDir;
const oldMakeTempDirSync: typeof Deno.makeTempDirSync = Deno.makeTempDirSync;
function makeTempFileSync(options?: Deno.MakeTempOptions) {
return withAttempts(() => oldMakeTempFileSync(options));
}
function makeTempFile(options?: Deno.MakeTempOptions) {
return withAttemptsAsync(() => oldMakeTempFile(options));
}
function makeTempDirSync(options?: Deno.MakeTempOptions) {
return withAttempts(() => oldMakeTempDirSync(options));
}
function makeTempDir(options?: Deno.MakeTempOptions) {
return withAttemptsAsync(() => oldMakeTempDir(options));
}
Deno.makeTempFile = makeTempFile;
Deno.makeTempFileSync = makeTempFileSync;
Deno.makeTempDir = makeTempDir;
Deno.makeTempDirSync = makeTempDirSync;
const oldReadTextFile: typeof Deno.readTextFile = Deno.readTextFile;
const oldReadTextFileSync: typeof Deno.readTextFileSync = Deno.readTextFileSync;
Deno.readTextFile = async (
path: string | URL,
options?: Deno.ReadFileOptions,
) => {
try {
const result = await oldReadTextFile(path, options);
return result;
} catch (err) {
if (!(err instanceof Error)) {
throw err;
}
if (err.message) {
err.message = err.message + "\n" + "Path: " + path;
}
throw err;
}
};
Deno.readTextFileSync = (path: string | URL) => {
try {
const result = oldReadTextFileSync(path);
return result;
} catch (err) {
if (!(err instanceof Error)) {
throw err;
}
if (err.message) {
err.message = err.message + "\n" + "Path: " + path;
}
throw err;
}
};