mirror of
https://github.com/denoland/deno.git
synced 2024-12-26 09:10:40 -05:00
93 lines
2.3 KiB
TypeScript
93 lines
2.3 KiB
TypeScript
|
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
|
||
|
|
||
|
import type { DenoWorkspaceCrate } from "./deno_workspace.ts";
|
||
|
|
||
|
export function getCratesPublishOrder(crates: DenoWorkspaceCrate[]) {
|
||
|
const pendingCrates = [...crates];
|
||
|
const sortedCrates = [];
|
||
|
|
||
|
while (pendingCrates.length > 0) {
|
||
|
for (let i = pendingCrates.length - 1; i >= 0; i--) {
|
||
|
const crate = pendingCrates[i];
|
||
|
const hasPendingDependency = crate.getDependencies()
|
||
|
.some((c) => pendingCrates.includes(c));
|
||
|
if (!hasPendingDependency) {
|
||
|
sortedCrates.push(crate);
|
||
|
pendingCrates.splice(i, 1);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return sortedCrates;
|
||
|
}
|
||
|
|
||
|
export function getGitLogFromTag(directory: string, tagName: string) {
|
||
|
return runCommand({
|
||
|
cwd: directory,
|
||
|
cmd: ["git", "log", "--oneline", `${tagName}..`],
|
||
|
});
|
||
|
}
|
||
|
|
||
|
export function formatGitLogForMarkdown(text: string) {
|
||
|
return text.split(/\r?\n/)
|
||
|
.map((line) => line.replace(/^[a-f0-9]{9} /i, "").trim())
|
||
|
.filter((l) => !l.startsWith("chore") && l.length > 0)
|
||
|
.sort()
|
||
|
.map((line) => `- ${line}`)
|
||
|
.join("\n");
|
||
|
}
|
||
|
|
||
|
export async function runCommand(params: {
|
||
|
cwd: string;
|
||
|
cmd: string[];
|
||
|
}) {
|
||
|
const p = Deno.run({
|
||
|
cwd: params.cwd,
|
||
|
cmd: params.cmd,
|
||
|
stderr: "piped",
|
||
|
stdout: "piped",
|
||
|
});
|
||
|
|
||
|
const [status, stdout, stderr] = await Promise.all([
|
||
|
p.status(),
|
||
|
p.output(),
|
||
|
p.stderrOutput(),
|
||
|
]);
|
||
|
p.close();
|
||
|
|
||
|
if (!status.success) {
|
||
|
throw new Error(
|
||
|
`Error executing ${params.cmd[0]}: ${new TextDecoder().decode(stderr)}`,
|
||
|
);
|
||
|
}
|
||
|
|
||
|
return new TextDecoder().decode(stdout);
|
||
|
}
|
||
|
|
||
|
export async function withRetries<TReturn>(params: {
|
||
|
action: () => Promise<TReturn>;
|
||
|
retryCount: number;
|
||
|
retryDelaySeconds: number;
|
||
|
}) {
|
||
|
for (let i = 0; i < params.retryCount; i++) {
|
||
|
if (i > 0) {
|
||
|
console.log(
|
||
|
`Failed. Trying again in ${params.retryDelaySeconds} seconds...`,
|
||
|
);
|
||
|
await delay(params.retryDelaySeconds * 1000);
|
||
|
console.log(`Attempt ${i + 1}/${params.retryCount}...`);
|
||
|
}
|
||
|
try {
|
||
|
return await params.action();
|
||
|
} catch (err) {
|
||
|
console.error(err);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
throw new Error(`Failed after ${params.retryCount} attempts.`);
|
||
|
}
|
||
|
|
||
|
function delay(ms: number) {
|
||
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||
|
}
|