Add OCR dependency support to plugin installer
Adds new flags `--drawj2d-jar` and `--install-deps` to handle OCR dependencies Automatically checks for required tools (unzip, Java, drawj2d.jar) Installs missing system packages when `--install-deps` is used Updates documentation with OCR setup examples The implementation includes dependency checking that can be skipped with `--skip-deps` when OCR functionality is not needed. The installer now copies and configures drawj2d.jar if provided, and updates the plugin's data.json accordingly.
This commit is contained in:
@@ -273,6 +273,10 @@ npm run install-plugin -- --vault /path/to/vault
|
||||
|
||||
# Exact target directory also works
|
||||
npm run install-plugin -- --plugin-dir /path/to/vault/.obsidian/plugins/obsidian-remarkable
|
||||
|
||||
# OCR dependency setup
|
||||
npm run install-plugin -- --vault /path/to/vault --drawj2d-jar /path/to/drawj2d.jar
|
||||
npm run install-plugin -- --vault /path/to/vault --install-deps
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
+159
-3
@@ -1,10 +1,12 @@
|
||||
import { copyFile, mkdir, readFile } from "fs/promises";
|
||||
import { dirname, join, resolve } from "path";
|
||||
import { access, copyFile, mkdir, readFile, writeFile } from "fs/promises";
|
||||
import { constants } from "fs";
|
||||
import { basename, dirname, join, resolve } from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
import { spawnSync } from "child_process";
|
||||
|
||||
const root = dirname(dirname(fileURLToPath(import.meta.url)));
|
||||
const runtimeFiles = ["manifest.json", "main.js"];
|
||||
const drawj2dTargetName = "drawj2d.jar";
|
||||
|
||||
function printUsage() {
|
||||
console.log(`Usage:
|
||||
@@ -14,22 +16,29 @@ function printUsage() {
|
||||
Options:
|
||||
--vault <path> Obsidian vault path. Installs to <vault>/.obsidian/plugins/<manifest id>
|
||||
--plugin-dir <path> Exact plugin install directory
|
||||
--drawj2d-jar <path> Copy a local drawj2d.jar into the plugin directory and configure it
|
||||
--install-deps Try to install missing system packages such as unzip
|
||||
--skip-deps Do not check OCR dependencies
|
||||
--no-build Skip npm run build before copying files
|
||||
--dry-run Print actions without writing files
|
||||
--help Show this help
|
||||
|
||||
Environment:
|
||||
OBSIDIAN_VAULT Same as --vault
|
||||
OBSIDIAN_PLUGIN_DIR Same as --plugin-dir`);
|
||||
OBSIDIAN_PLUGIN_DIR Same as --plugin-dir
|
||||
DRAWJ2D_JAR Same as --drawj2d-jar`);
|
||||
}
|
||||
|
||||
function parseArgs(argv) {
|
||||
const options = {
|
||||
vault: process.env.OBSIDIAN_VAULT || "",
|
||||
pluginDir: process.env.OBSIDIAN_PLUGIN_DIR || "",
|
||||
drawj2dJar: process.env.DRAWJ2D_JAR || "",
|
||||
build: true,
|
||||
dryRun: false,
|
||||
help: false,
|
||||
installDeps: false,
|
||||
skipDeps: false,
|
||||
};
|
||||
|
||||
for (let i = 0; i < argv.length; i++) {
|
||||
@@ -41,10 +50,16 @@ function parseArgs(argv) {
|
||||
options.build = false;
|
||||
} else if (arg === "--dry-run") {
|
||||
options.dryRun = true;
|
||||
} else if (arg === "--install-deps") {
|
||||
options.installDeps = true;
|
||||
} else if (arg === "--skip-deps") {
|
||||
options.skipDeps = true;
|
||||
} else if (arg === "--vault") {
|
||||
options.vault = argv[++i] || "";
|
||||
} else if (arg === "--plugin-dir") {
|
||||
options.pluginDir = argv[++i] || "";
|
||||
} else if (arg === "--drawj2d-jar") {
|
||||
options.drawj2dJar = argv[++i] || "";
|
||||
} else {
|
||||
throw new Error(`Unknown option: ${arg}`);
|
||||
}
|
||||
@@ -79,6 +94,142 @@ function runBuild() {
|
||||
}
|
||||
}
|
||||
|
||||
function run(command, args, options = {}) {
|
||||
return spawnSync(command, args, {
|
||||
cwd: root,
|
||||
stdio: options.stdio || "pipe",
|
||||
encoding: "utf-8",
|
||||
});
|
||||
}
|
||||
|
||||
function commandExists(command, args) {
|
||||
const result = run(command, args);
|
||||
return !result.error && result.status === 0;
|
||||
}
|
||||
|
||||
function detectPackageInstallCommand(packageName) {
|
||||
if (commandExists("apt-get", ["--version"])) {
|
||||
return ["sudo", ["apt-get", "install", "-y", packageName]];
|
||||
}
|
||||
if (commandExists("dnf", ["--version"])) {
|
||||
return ["sudo", ["dnf", "install", "-y", packageName]];
|
||||
}
|
||||
if (commandExists("pacman", ["--version"])) {
|
||||
return ["sudo", ["pacman", "-S", "--needed", "--noconfirm", packageName]];
|
||||
}
|
||||
if (commandExists("brew", ["--version"])) {
|
||||
return ["brew", ["install", packageName]];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function installPackage(packageName, dryRun) {
|
||||
const command = detectPackageInstallCommand(packageName);
|
||||
if (!command) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const [binary, args] = command;
|
||||
console.log(`${dryRun ? "Would run" : "Running"} ${binary} ${args.join(" ")}`);
|
||||
if (dryRun) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const result = spawnSync(binary, args, { stdio: "inherit" });
|
||||
if (result.error) {
|
||||
throw result.error;
|
||||
}
|
||||
return result.status === 0;
|
||||
}
|
||||
|
||||
async function fileExists(path) {
|
||||
try {
|
||||
await access(path, constants.R_OK);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function checkDependencies(options, targetDir) {
|
||||
const missing = [];
|
||||
|
||||
if (!commandExists("unzip", ["-v"])) {
|
||||
if (options.installDeps && installPackage("unzip", options.dryRun)) {
|
||||
console.log(options.dryRun ? "unzip would be installed." : "Installed unzip.");
|
||||
} else {
|
||||
missing.push("unzip");
|
||||
}
|
||||
}
|
||||
|
||||
if (!commandExists("java", ["-version"])) {
|
||||
missing.push("java");
|
||||
}
|
||||
|
||||
const targetDrawj2dPath = join(targetDir, drawj2dTargetName);
|
||||
const sourceDrawj2dPath = options.drawj2dJar ? resolve(options.drawj2dJar) : "";
|
||||
const hasSourceDrawj2d = sourceDrawj2dPath ? await fileExists(sourceDrawj2dPath) : false;
|
||||
const hasInstalledDrawj2d = await fileExists(targetDrawj2dPath);
|
||||
|
||||
if (sourceDrawj2dPath && !hasSourceDrawj2d) {
|
||||
missing.push(`drawj2d jar at ${sourceDrawj2dPath}`);
|
||||
} else if (!hasSourceDrawj2d && !hasInstalledDrawj2d) {
|
||||
missing.push("drawj2d.jar");
|
||||
}
|
||||
|
||||
if (missing.length > 0) {
|
||||
throw new Error(
|
||||
[
|
||||
`Missing dependencies: ${missing.join(", ")}`,
|
||||
"Install unzip and Java with your system package manager.",
|
||||
"Download drawj2d.jar, then rerun with --drawj2d-jar /path/to/drawj2d.jar or set DRAWJ2D_JAR.",
|
||||
"Use --skip-deps only if you intentionally do not want OCR dependency checks.",
|
||||
].join("\n"),
|
||||
);
|
||||
}
|
||||
|
||||
return sourceDrawj2dPath && hasSourceDrawj2d ? sourceDrawj2dPath : "";
|
||||
}
|
||||
|
||||
async function installDrawj2dJar(sourcePath, targetDir, dryRun) {
|
||||
if (!sourcePath) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (basename(sourcePath) !== drawj2dTargetName) {
|
||||
console.log(`Installing ${basename(sourcePath)} as ${drawj2dTargetName}`);
|
||||
}
|
||||
|
||||
const destination = join(targetDir, drawj2dTargetName);
|
||||
console.log(`${dryRun ? "Would copy" : "Copying"} ${drawj2dTargetName}`);
|
||||
|
||||
if (!dryRun) {
|
||||
await copyFile(sourcePath, destination);
|
||||
}
|
||||
|
||||
return destination;
|
||||
}
|
||||
|
||||
async function updatePluginData(targetDir, drawj2dPath, dryRun) {
|
||||
if (!drawj2dPath) {
|
||||
return;
|
||||
}
|
||||
|
||||
const dataPath = join(targetDir, "data.json");
|
||||
let data = {};
|
||||
|
||||
if (await fileExists(dataPath)) {
|
||||
data = JSON.parse(await readFile(dataPath, "utf-8"));
|
||||
}
|
||||
|
||||
data.drawj2dPath = drawj2dPath;
|
||||
console.log(`${dryRun ? "Would update" : "Updating"} data.json drawj2dPath`);
|
||||
|
||||
if (!dryRun) {
|
||||
await writeFile(dataPath, `${JSON.stringify(data, null, 2)}\n`);
|
||||
}
|
||||
}
|
||||
|
||||
async function install() {
|
||||
const options = parseArgs(process.argv.slice(2));
|
||||
|
||||
@@ -108,6 +259,8 @@ async function install() {
|
||||
runBuild();
|
||||
}
|
||||
|
||||
const drawj2dJarToInstall = options.skipDeps ? "" : await checkDependencies(options, targetDir);
|
||||
|
||||
console.log(`Installing to ${targetDir}`);
|
||||
|
||||
if (!options.dryRun) {
|
||||
@@ -124,6 +277,9 @@ async function install() {
|
||||
}
|
||||
}
|
||||
|
||||
const installedDrawj2dPath = await installDrawj2dJar(drawj2dJarToInstall, targetDir, options.dryRun);
|
||||
await updatePluginData(targetDir, installedDrawj2dPath || (!options.skipDeps ? join(targetDir, drawj2dTargetName) : ""), options.dryRun);
|
||||
|
||||
console.log("Install complete.");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user