Skip to content

Instantly share code, notes, and snippets.

@luixo
Last active December 7, 2023 05:15
Show Gist options
  • Select an option

  • Save luixo/e6669fbb68aa318cc8d560a2d3e25607 to your computer and use it in GitHub Desktop.

Select an option

Save luixo/e6669fbb68aa318cc8d560a2d3e25607 to your computer and use it in GitHub Desktop.
deno run ../patch.mts <package>
/* eslint-disable no-restricted-syntax, no-console */
import { $ } from "npm:execa@latest";
import * as path from "https://deno.land/[email protected]/path/mod.ts";
const getPath = (relativePath: string) => {
const cwd = Deno.cwd();
return path.join(cwd, relativePath);
};
const decoder = new TextDecoder("utf-8");
const encoder = new TextEncoder();
const run = async (packageName?: string) => {
if (!packageName) {
throw new Error("Expected a package name");
}
console.log(`Patching package "${packageName}"`);
let version;
try {
const packageJson = JSON.parse(
decoder.decode(
await Deno.readFile(
getPath(`./node_modules/${packageName}/package.json`)
)
)
);
if (!packageJson.version) {
throw new Error("No version field in package.json");
}
version = packageJson.version;
} catch (e) {
throw new Error("Couldn't evaluate package version", { cause: e });
}
console.log(`Patching ${packageName}@${version}`);
const patchResult = await $`yarn patch --json ${packageName}@npm:${version}`;
const jsonResult = JSON.parse(patchResult.stdout);
if (!jsonResult.path) {
throw new Error("Couldn't find patch path");
}
console.log(`Patch dir: ${jsonResult.path}`);
await $`rm -rf ${jsonResult.path}`;
await $`cp -r node_modules/${packageName} ${jsonResult.path}`;
await $`rm -rf ${jsonResult.path}/node_modules`;
await $`yarn patch-commit -s ${jsonResult.path}`;
const patchFilenames = await Deno.readDir(getPath(`./patches`));
let patchFilename: string | undefined;
for await (const filenameCandidate of patchFilenames) {
if (filenameCandidate.name.startsWith(packageName)) {
patchFilename = filenameCandidate.name;
break;
}
}
if (!patchFilename) {
throw new Error("Patch was not save to patches dir");
}
const hashlessPatchFilename = patchFilename.replace(
/-[a-z0-9]*\.patch/,
".patch"
);
await Deno.rename(
getPath(`./patches/${patchFilename}`),
getPath(`./patches/${hashlessPatchFilename}`)
);
console.log(`Patch file name: ${hashlessPatchFilename}`);
const localPackageJson = JSON.parse(
decoder.decode(await Deno.readFile(getPath("./package.json")))
);
const resolutionKey = Object.keys(localPackageJson.resolutions).find((key) =>
key.startsWith(packageName!)
);
if (!resolutionKey) {
throw new Error("Resolution was not save to package.json");
}
const resolution = localPackageJson.resolutions[resolutionKey];
localPackageJson.resolutions[resolutionKey] = resolution.replace(
patchFilename,
hashlessPatchFilename
);
await Deno.writeFile(
"package.json",
encoder.encode(`${JSON.stringify(localPackageJson, null, " ")}\n`)
);
};
await run(Deno.args[0]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment