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
|
# Exact target directory also works
|
||||||
npm run install-plugin -- --plugin-dir /path/to/vault/.obsidian/plugins/obsidian-remarkable
|
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 { access, copyFile, mkdir, readFile, writeFile } from "fs/promises";
|
||||||
import { dirname, join, resolve } from "path";
|
import { constants } from "fs";
|
||||||
|
import { basename, dirname, join, resolve } from "path";
|
||||||
import { fileURLToPath } from "url";
|
import { fileURLToPath } from "url";
|
||||||
import { spawnSync } from "child_process";
|
import { spawnSync } from "child_process";
|
||||||
|
|
||||||
const root = dirname(dirname(fileURLToPath(import.meta.url)));
|
const root = dirname(dirname(fileURLToPath(import.meta.url)));
|
||||||
const runtimeFiles = ["manifest.json", "main.js"];
|
const runtimeFiles = ["manifest.json", "main.js"];
|
||||||
|
const drawj2dTargetName = "drawj2d.jar";
|
||||||
|
|
||||||
function printUsage() {
|
function printUsage() {
|
||||||
console.log(`Usage:
|
console.log(`Usage:
|
||||||
@@ -14,22 +16,29 @@ function printUsage() {
|
|||||||
Options:
|
Options:
|
||||||
--vault <path> Obsidian vault path. Installs to <vault>/.obsidian/plugins/<manifest id>
|
--vault <path> Obsidian vault path. Installs to <vault>/.obsidian/plugins/<manifest id>
|
||||||
--plugin-dir <path> Exact plugin install directory
|
--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
|
--no-build Skip npm run build before copying files
|
||||||
--dry-run Print actions without writing files
|
--dry-run Print actions without writing files
|
||||||
--help Show this help
|
--help Show this help
|
||||||
|
|
||||||
Environment:
|
Environment:
|
||||||
OBSIDIAN_VAULT Same as --vault
|
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) {
|
function parseArgs(argv) {
|
||||||
const options = {
|
const options = {
|
||||||
vault: process.env.OBSIDIAN_VAULT || "",
|
vault: process.env.OBSIDIAN_VAULT || "",
|
||||||
pluginDir: process.env.OBSIDIAN_PLUGIN_DIR || "",
|
pluginDir: process.env.OBSIDIAN_PLUGIN_DIR || "",
|
||||||
|
drawj2dJar: process.env.DRAWJ2D_JAR || "",
|
||||||
build: true,
|
build: true,
|
||||||
dryRun: false,
|
dryRun: false,
|
||||||
help: false,
|
help: false,
|
||||||
|
installDeps: false,
|
||||||
|
skipDeps: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
for (let i = 0; i < argv.length; i++) {
|
for (let i = 0; i < argv.length; i++) {
|
||||||
@@ -41,10 +50,16 @@ function parseArgs(argv) {
|
|||||||
options.build = false;
|
options.build = false;
|
||||||
} else if (arg === "--dry-run") {
|
} else if (arg === "--dry-run") {
|
||||||
options.dryRun = true;
|
options.dryRun = true;
|
||||||
|
} else if (arg === "--install-deps") {
|
||||||
|
options.installDeps = true;
|
||||||
|
} else if (arg === "--skip-deps") {
|
||||||
|
options.skipDeps = true;
|
||||||
} else if (arg === "--vault") {
|
} else if (arg === "--vault") {
|
||||||
options.vault = argv[++i] || "";
|
options.vault = argv[++i] || "";
|
||||||
} else if (arg === "--plugin-dir") {
|
} else if (arg === "--plugin-dir") {
|
||||||
options.pluginDir = argv[++i] || "";
|
options.pluginDir = argv[++i] || "";
|
||||||
|
} else if (arg === "--drawj2d-jar") {
|
||||||
|
options.drawj2dJar = argv[++i] || "";
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Unknown option: ${arg}`);
|
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() {
|
async function install() {
|
||||||
const options = parseArgs(process.argv.slice(2));
|
const options = parseArgs(process.argv.slice(2));
|
||||||
|
|
||||||
@@ -108,6 +259,8 @@ async function install() {
|
|||||||
runBuild();
|
runBuild();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const drawj2dJarToInstall = options.skipDeps ? "" : await checkDependencies(options, targetDir);
|
||||||
|
|
||||||
console.log(`Installing to ${targetDir}`);
|
console.log(`Installing to ${targetDir}`);
|
||||||
|
|
||||||
if (!options.dryRun) {
|
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.");
|
console.log("Install complete.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user