111 lines
3.7 KiB
TypeScript
111 lines
3.7 KiB
TypeScript
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { spawnSync } from "node:child_process";
|
|
|
|
const root = path.resolve(import.meta.dir, "..");
|
|
const krita = path.join(root, "krita");
|
|
const patchDir = path.join(root, "krita-patches");
|
|
const patchFile = path.join(patchDir, "xiaomi-eink.patch");
|
|
// Keep generated patches limited to this project. The nested Krita checkout may carry
|
|
// line-ending or formatter changes that are not part of the E Ink product patch.
|
|
const patchPaths = [
|
|
"CMakeLists.txt",
|
|
"libs/ui/KisApplication.cpp",
|
|
"libs/ui/KisMainWindow.cpp",
|
|
"libs/ui/thememanager.cpp",
|
|
"packaging/android/apk/AndroidManifest.xml",
|
|
"packaging/android/apk/build.gradle",
|
|
"packaging/android/apk/proguard-rules.pro",
|
|
"packaging/android/apk/src/org/krita/android/MainActivity.java",
|
|
"plugins/CMakeLists.txt",
|
|
"plugins/dockers/CMakeLists.txt",
|
|
"plugins/filters/CMakeLists.txt",
|
|
"plugins/impex/CMakeLists.txt",
|
|
"plugins/paintops/CMakeLists.txt",
|
|
"plugins/tools/CMakeLists.txt",
|
|
];
|
|
const untrackedPatchPaths = [
|
|
"EINK_SLIM.md",
|
|
"packaging/android/apk/.gitignore",
|
|
"packaging/android/apk/settings.gradle",
|
|
"packaging/android/apk/lib/arm64-v8a/libfakeRKEpdUtils.so",
|
|
"packaging/android/apk/src/com/moan/fakerkepdlib/EpdUtil.java",
|
|
"packaging/android/apk/src/org/krita/android/XiaomiEinkController.java",
|
|
"plugins/dockers/einkmonochromeselector/CMakeLists.txt",
|
|
"plugins/dockers/einkmonochromeselector/einkmonochromeselector.cpp",
|
|
"plugins/dockers/einkmonochromeselector/krita_einkmonochromeselector.json",
|
|
"plugins/extensions/einksync/CMakeLists.txt",
|
|
"plugins/extensions/einksync/EinkSyncPlugin.action",
|
|
"plugins/extensions/einksync/EinkSyncPlugin.cpp",
|
|
"plugins/extensions/einksync/kritaeinksync.json",
|
|
];
|
|
|
|
function git(args: string[], allowDifference = false): string {
|
|
const result = spawnSync("git", ["-C", krita, ...args], {
|
|
encoding: "utf8",
|
|
maxBuffer: 128 * 1024 * 1024,
|
|
});
|
|
if (result.error) throw result.error;
|
|
if (result.status !== 0 && !(allowDifference && result.status === 1)) {
|
|
throw new Error(result.stderr || `git ${args.join(" ")} failed`);
|
|
}
|
|
return result.stdout;
|
|
}
|
|
|
|
function generate(): void {
|
|
fs.mkdirSync(patchDir, { recursive: true });
|
|
let output = git([
|
|
"diff",
|
|
"--binary",
|
|
"--ignore-space-at-eol",
|
|
"--",
|
|
...patchPaths,
|
|
]);
|
|
const available = new Set(
|
|
git(["ls-files", "--others", "--exclude-standard"])
|
|
.split("\n")
|
|
.filter(Boolean),
|
|
);
|
|
const untracked = untrackedPatchPaths.filter((file) => available.has(file));
|
|
for (const file of untracked) {
|
|
output += git(
|
|
["diff", "--no-index", "--binary", "--", "/dev/null", file],
|
|
true,
|
|
);
|
|
}
|
|
if (!output.trim()) throw new Error("Krita has no changes to package");
|
|
fs.writeFileSync(patchFile, output);
|
|
console.log(`[ok] Generated ${patchFile} with ${untracked.length} new files`);
|
|
}
|
|
|
|
function apply(): void {
|
|
if (!fs.existsSync(path.join(krita, ".git")))
|
|
throw new Error("Initialize the Krita submodule first");
|
|
if (!fs.existsSync(patchFile)) throw new Error(`Missing ${patchFile}`);
|
|
const applyArgs = ["apply", "--ignore-space-change", "--recount"];
|
|
const check = spawnSync(
|
|
"git",
|
|
["-C", krita, ...applyArgs, "--check", patchFile],
|
|
{
|
|
encoding: "utf8",
|
|
},
|
|
);
|
|
if (check.status === 0) {
|
|
git([...applyArgs, "--whitespace=nowarn", patchFile]);
|
|
console.log("[ok] Applied E Ink Krita patch set");
|
|
return;
|
|
}
|
|
const reverse = spawnSync(
|
|
"git",
|
|
["-C", krita, ...applyArgs, "--reverse", "--check", patchFile],
|
|
{ encoding: "utf8" },
|
|
);
|
|
if (reverse.status === 0) {
|
|
console.log("[ok] E Ink Krita patch set is already applied");
|
|
return;
|
|
}
|
|
throw new Error(`Patch does not apply cleanly\n${check.stderr}`);
|
|
}
|
|
|
|
if (process.argv.includes("--generate")) generate();
|
|
else apply();
|