deno/tools/update_tsgo.ts
Nathan Whitaker b252cc78c2
feat(unstable): typescript-go integration for deno check (#30920)
Integrated only with deno check (and test, `run --check`, etc)
currently. All spec tests for deno check pass except for 3, which i've
disabled

---------

Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com>
Co-authored-by: Divy Srivastava <me@littledivy.com>
2025-10-20 09:59:54 -07:00

195 lines
4.8 KiB
TypeScript
Executable file

#!/usr/bin/env -S deno run -RWN --allow-run=deno
// Copyright 2018-2025 the Deno authors. MIT license.
// deno-lint-ignore-file no-console
import { fileURLToPath } from "node:url";
/**
* Trims the minimum indent from each line of a multiline string,
* removing leading and trailing blank lines.
* @param text
* @returns the trimmed string
*/
export function trimIndent(text: string): string {
if (text.startsWith("\n")) {
text = text.slice(1);
}
const lines = text.split("\n");
const nonEmptyLines = lines.filter((line) => line.trim().length > 0);
const indent = nonEmptyLines.length > 0
? Math.min(
...nonEmptyLines.map((line) => line.length - line.trimStart().length),
)
: 0;
return lines
.map((line) => {
if (line.length <= indent) {
return line.replace(/^ +/, "");
} else {
return line.slice(indent);
}
})
.join("\n");
}
export function unindent(strings: TemplateStringsArray, ...values: unknown[]) {
// normal template substitution
const raw = String.raw({ raw: strings }, ...values);
return trimIndent(raw);
}
const repo = "denoland/typescript-go";
interface GitHubRelease {
"tag_name": string;
assets: GitHubAsset[];
}
interface GitHubAsset {
name: string;
digest: string; // sha256:...
}
const latestResponse = await fetch(
`https://api.github.com/repos/${repo}/releases/latest`,
);
if (!latestResponse.ok) {
throw new Error(
`Failed to fetch latest release: ${latestResponse.statusText}`,
);
}
const latest = await latestResponse.json() as GitHubRelease;
const version = latest.tag_name;
const versionNoV = version.replace(/^v/, "");
const file = fileURLToPath(import.meta.resolve(
"../cli/tsc/go/tsgo_version.rs",
));
const content = await Deno.readTextFile(file);
const match = content.match(/const VERSION: &str = "([^"]+)"/);
let currentVersion = "";
if (!match) {
currentVersion = "";
} else {
currentVersion = match[1];
}
console.log("Current version: ", currentVersion);
if (currentVersion === versionNoV) {
console.log("Version is up to date, updating generated code");
} else {
console.log("Updating version to: ", versionNoV);
}
function findHashes(
release: GitHubRelease,
): {
windowsX64: string;
macosX64: string;
macosArm64: string;
linuxX64: string;
linuxArm64: string;
} {
const hashes = {
windowsX64: "",
macosX64: "",
macosArm64: "",
linuxX64: "",
linuxArm64: "",
};
for (const asset of release.assets) {
const parts = asset.name.split("-");
const os = parts[parts.length - 2];
const archAndExtension = parts[parts.length - 1];
const arch = archAndExtension.split(".")[0];
if (os === "windows" && arch === "x64") {
hashes.windowsX64 = asset.digest;
} else if (os === "macos" && arch === "x64") {
hashes.macosX64 = asset.digest;
} else if (os === "macos" && arch === "arm64") {
hashes.macosArm64 = asset.digest;
} else if (os === "linux" && arch === "x64") {
hashes.linuxX64 = asset.digest;
} else if (os === "linux" && arch === "arm64") {
hashes.linuxArm64 = asset.digest;
}
}
return hashes;
}
const hashes = findHashes(latest);
for (const [platform, hash] of Object.entries(hashes)) {
if (!hash) {
console.error(`No hashes found for ${platform}`);
Deno.exit(1);
}
}
const newContent = unindent`
// Copyright 2018-2025 the Deno authors. MIT license.
// This file is auto-generated by tools/update_tsgo.ts
// DO NOT EDIT THIS FILE MANUALLY
pub struct Hashes {
pub windows_x64: &'static str,
pub macos_x64: &'static str,
pub macos_arm64: &'static str,
pub linux_x64: &'static str,
pub linux_arm64: &'static str,
}
impl Hashes {
pub const fn all(&self) -> [&'static str; 5] {
[
self.windows_x64,
self.macos_x64,
self.macos_arm64,
self.linux_x64,
self.linux_arm64,
]
}
}
pub const VERSION: &str = "${versionNoV}";
pub const DOWNLOAD_BASE_URL: &str =
"https://github.com/${repo}/releases/download/${version}";
pub const HASHES: Hashes = Hashes {
windows_x64: "${hashes.windowsX64}",
macos_x64: "${hashes.macosX64}",
macos_arm64: "${hashes.macosArm64}",
linux_x64: "${hashes.linuxX64}",
linux_arm64: "${hashes.linuxArm64}",
};
const _: () = {
let sha256 = "sha256".as_bytes();
let mut i = 0;
let hashes = HASHES.all();
while i < hashes.len() {
let hash = hashes[i].as_bytes();
let mut j = 0;
while j < 6 {
if hash[j] != sha256[j] {
panic!("Hash algorithm is not sha256");
}
j += 1;
}
i += 1;
}
};
`;
await Deno.writeTextFile(file, newContent);
if (currentVersion !== versionNoV) {
console.log("Version updated to ", versionNoV);
}
await import("./format.js");