mirror of
https://github.com/amitwh/markdown-converter.git
synced 2026-10-01 17:29:29 +05:30
build(release): dynamic builder config + fix bundled-tool lookup in packages
- electron-builder config moves to electron-builder.config.js so markitdown bundling is conditional per platform (PyInstaller only builds for the host OS; a missing binary now logs a warning and ships without it instead of failing the build); package.json static build section removed, all npm scripts pointed at the config; third-party-licenses/ added to packaged files - FIX (pre-existing): packaged apps looked for bundled pandoc in resources/bin, but extraFiles land next to the executable (Contents/ on macOS) — packaged builds silently fell back to system pandoc since 4.5. New bundledToolDir() resolves the real location for pandoc + markitdown - download-tools.js pins the win32 pandoc.exe SHA-256 (fetched + verified) - sharp packaging test accepts sharp 0.35's versioned binding filename - release.yml: bundle-markitdown step (best-effort) on every OS and a new macOS job; release aggregates linux+windows+macos artifacts Local release artifacts built and verified (dist/): - MarkdownConverter-4.7.0.AppImage (363MB, pandoc+markitdown bundled, packaged app boots clean, tools resolve at the fixed path) - markdown-converter_4.7.0_amd64.deb (293MB) - MarkdownConverter-Setup-4.7.0.exe (223MB), portable exe (223MB), zip (305MB) — pandoc bundled; markitdown omitted (cannot cross-build), legal docs verified inside app.asar 637/637 tests green; lint clean.
This commit is contained in:
@@ -25,6 +25,13 @@ jobs:
|
|||||||
- name: Download external tools (pandoc)
|
- name: Download external tools (pandoc)
|
||||||
run: node scripts/download-tools.js
|
run: node scripts/download-tools.js
|
||||||
|
|
||||||
|
- name: Bundle MarkItDown (optional, best effort)
|
||||||
|
# Freezes markitdown + Python into bin/linux/markitdown; failure is
|
||||||
|
# non-fatal — the build then ships without it and the app falls back
|
||||||
|
# to a system markitdown at runtime.
|
||||||
|
run: npm run bundle:markitdown
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: npm test
|
run: npm test
|
||||||
|
|
||||||
@@ -59,6 +66,12 @@ jobs:
|
|||||||
- name: Download external tools (pandoc)
|
- name: Download external tools (pandoc)
|
||||||
run: node scripts/download-tools.js
|
run: node scripts/download-tools.js
|
||||||
|
|
||||||
|
- name: Bundle MarkItDown (optional, best effort)
|
||||||
|
# Windows runners ship python + venv; non-fatal on failure — the
|
||||||
|
# package then omits the bundled binary by design
|
||||||
|
run: npm run bundle:markitdown
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: npm test
|
run: npm test
|
||||||
|
|
||||||
@@ -94,8 +107,44 @@ jobs:
|
|||||||
dist/*.zip
|
dist/*.zip
|
||||||
retention-days: 5
|
retention-days: 5
|
||||||
|
|
||||||
|
build-macos:
|
||||||
|
runs-on: macos-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
cache: npm
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Download external tools (pandoc)
|
||||||
|
run: node scripts/download-tools.js
|
||||||
|
|
||||||
|
- name: Bundle MarkItDown (optional, best effort)
|
||||||
|
run: npm run bundle:markitdown
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: npm test
|
||||||
|
|
||||||
|
- name: Build macOS packages
|
||||||
|
run: npm run build:mac -- --publish=never
|
||||||
|
|
||||||
|
- name: Upload macOS artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: macos-artifacts
|
||||||
|
path: |
|
||||||
|
dist/*.dmg
|
||||||
|
dist/*.zip
|
||||||
|
retention-days: 5
|
||||||
|
|
||||||
release:
|
release:
|
||||||
needs: [build-linux, build-windows]
|
needs: [build-linux, build-windows, build-macos]
|
||||||
if: always()
|
if: always()
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@@ -115,6 +164,13 @@ jobs:
|
|||||||
name: windows-artifacts
|
name: windows-artifacts
|
||||||
path: dist
|
path: dist
|
||||||
|
|
||||||
|
- name: Download macOS artifacts
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
continue-on-error: true
|
||||||
|
with:
|
||||||
|
name: macos-artifacts
|
||||||
|
path: dist
|
||||||
|
|
||||||
- name: Create GitHub Release
|
- name: Create GitHub Release
|
||||||
uses: softprops/action-gh-release@v2
|
uses: softprops/action-gh-release@v2
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -0,0 +1,124 @@
|
|||||||
|
/**
|
||||||
|
* electron-builder configuration (replaces the static package.json "build"
|
||||||
|
* section so it can be computed dynamically).
|
||||||
|
*
|
||||||
|
* Why a JS config: the bundled markitdown binary is OPTIONAL at build time —
|
||||||
|
* PyInstaller can only build for the host OS, so e.g. a Windows package
|
||||||
|
* built on a machine without bin/win32/markitdown.exe must simply omit it
|
||||||
|
* (the app falls back to system-installed markitdown at runtime) instead of
|
||||||
|
* failing on a missing extraFiles source.
|
||||||
|
*
|
||||||
|
* Everything else mirrors the previous static config verbatim.
|
||||||
|
*/
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
/** Common extraFiles for a platform: pandoc always, markitdown when built. */
|
||||||
|
function toolExtraFiles(platform) {
|
||||||
|
const exe = platform === 'win32' ? '.exe' : '';
|
||||||
|
const files = [{ from: `bin/${platform}/pandoc${exe}`, to: `bin/pandoc${exe}` }];
|
||||||
|
const markitdown = `bin/${platform}/markitdown${exe}`;
|
||||||
|
if (fs.existsSync(path.join(__dirname, markitdown))) {
|
||||||
|
files.push({ from: markitdown, to: `bin/markitdown${exe}` });
|
||||||
|
} else {
|
||||||
|
console.warn(
|
||||||
|
`[electron-builder.config] ${markitdown} not found — building WITHOUT the ` +
|
||||||
|
'bundled markitdown (the app will use a system install if present). ' +
|
||||||
|
'Run "npm run bundle:markitdown" on this platform to bundle it.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
appId: 'com.concreteinfo.markdownconverter',
|
||||||
|
productName: 'MarkdownConverter',
|
||||||
|
copyright: 'Copyright (C) 2024-2025 ConcreteInfo',
|
||||||
|
directories: { output: 'dist' },
|
||||||
|
icon: 'assets/icon',
|
||||||
|
files: [
|
||||||
|
'src/**/*',
|
||||||
|
'assets/**/*',
|
||||||
|
'scripts/**/*',
|
||||||
|
'node_modules/**/*',
|
||||||
|
'package.json',
|
||||||
|
'THIRD-PARTY-NOTICES.md',
|
||||||
|
'SOURCES.md',
|
||||||
|
'third-party-licenses/**/*',
|
||||||
|
],
|
||||||
|
asarUnpack: [
|
||||||
|
'node_modules/ffmpeg-static/**',
|
||||||
|
'node_modules/sharp/**',
|
||||||
|
'node_modules/@img/**',
|
||||||
|
'node_modules/@napi-rs/**',
|
||||||
|
'assets/fonts/**',
|
||||||
|
],
|
||||||
|
fileAssociations: [
|
||||||
|
{
|
||||||
|
ext: 'md',
|
||||||
|
name: 'Markdown Document',
|
||||||
|
description: 'Markdown Document',
|
||||||
|
mimeType: 'text/markdown',
|
||||||
|
role: 'Editor',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ext: 'markdown',
|
||||||
|
name: 'Markdown Document',
|
||||||
|
description: 'Markdown Document',
|
||||||
|
mimeType: 'text/markdown',
|
||||||
|
role: 'Editor',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ext: 'pdf',
|
||||||
|
name: 'PDF Document',
|
||||||
|
description: 'PDF Document',
|
||||||
|
mimeType: 'application/pdf',
|
||||||
|
role: 'Editor',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
mac: {
|
||||||
|
category: 'public.app-category.productivity',
|
||||||
|
identity: null,
|
||||||
|
extraFiles: toolExtraFiles('darwin'),
|
||||||
|
},
|
||||||
|
win: {
|
||||||
|
target: [
|
||||||
|
{ target: 'nsis', arch: ['x64'] },
|
||||||
|
{ target: 'portable', arch: ['x64'] },
|
||||||
|
{ target: 'zip', arch: ['x64'] },
|
||||||
|
],
|
||||||
|
artifactName: '${productName}-${version}-${arch}.${ext}',
|
||||||
|
requestedExecutionLevel: 'asInvoker',
|
||||||
|
legalTrademarks: 'Copyright (C) 2024-2025 ConcreteInfo',
|
||||||
|
verifyUpdateCodeSignature: false,
|
||||||
|
signAndEditExecutable: false,
|
||||||
|
extraFiles: toolExtraFiles('win32'),
|
||||||
|
},
|
||||||
|
nsis: {
|
||||||
|
oneClick: false,
|
||||||
|
perMachine: false,
|
||||||
|
allowToChangeInstallationDirectory: true,
|
||||||
|
displayLanguageSelector: true,
|
||||||
|
createDesktopShortcut: true,
|
||||||
|
createStartMenuShortcut: true,
|
||||||
|
shortcutName: 'MarkdownConverter',
|
||||||
|
runAfterFinish: true,
|
||||||
|
menuCategory: 'Productivity',
|
||||||
|
license: 'LICENSE',
|
||||||
|
warningsAsErrors: false,
|
||||||
|
artifactName: '${productName}-Setup-${version}.${ext}',
|
||||||
|
deleteAppDataOnUninstall: false,
|
||||||
|
differentialPackage: true,
|
||||||
|
},
|
||||||
|
linux: {
|
||||||
|
target: ['deb', 'AppImage', 'snap'],
|
||||||
|
category: 'Utility',
|
||||||
|
maintainer: 'ConcreteInfo <amit.wh@gmail.com>',
|
||||||
|
extraFiles: toolExtraFiles('linux'),
|
||||||
|
},
|
||||||
|
deb: {
|
||||||
|
depends: ['imagemagick', 'libreoffice-common'],
|
||||||
|
description: 'Professional Markdown editor and universal file converter',
|
||||||
|
maintainer: 'ConcreteInfo <amit.wh@gmail.com>',
|
||||||
|
},
|
||||||
|
};
|
||||||
+10
-153
@@ -12,17 +12,17 @@
|
|||||||
"lint:fix": "eslint src tests --fix",
|
"lint:fix": "eslint src tests --fix",
|
||||||
"format": "prettier --write src tests",
|
"format": "prettier --write src tests",
|
||||||
"format:check": "prettier --check src tests",
|
"format:check": "prettier --check src tests",
|
||||||
"build": "electron-builder",
|
"build": "electron-builder --config electron-builder.config.js",
|
||||||
"build:win": "electron-builder --win",
|
"build:win": "electron-builder --config electron-builder.config.js --win",
|
||||||
"build:win-signed": "cross-env CSC_LINK=code-signing-cert.pfx electron-builder --win",
|
"build:win-signed": "cross-env CSC_LINK=code-signing-cert.pfx electron-builder --config electron-builder.config.js --win",
|
||||||
"build:win-unsigned": "cross-env CSC_IDENTITY_AUTO_DISCOVERY=false electron-builder --win",
|
"build:win-unsigned": "cross-env CSC_IDENTITY_AUTO_DISCOVERY=false electron-builder --config electron-builder.config.js --win",
|
||||||
"create-cert": "powershell -ExecutionPolicy Bypass -File scripts/create-selfsigned-cert.ps1",
|
"create-cert": "powershell -ExecutionPolicy Bypass -File scripts/create-selfsigned-cert.ps1",
|
||||||
"build:mac": "electron-builder --mac",
|
"build:mac": "electron-builder --config electron-builder.config.js --mac",
|
||||||
"build:linux": "electron-builder --linux",
|
"build:linux": "electron-builder --config electron-builder.config.js --linux",
|
||||||
"build:linux-ci": "electron-builder --linux deb AppImage",
|
"build:linux-ci": "electron-builder --config electron-builder.config.js --linux deb AppImage",
|
||||||
"build:local": "electron-builder --linux --win",
|
"build:local": "electron-builder --config electron-builder.config.js --linux --win",
|
||||||
"dist": "electron-builder --publish=never",
|
"dist": "electron-builder --config electron-builder.config.js --publish=never",
|
||||||
"dist:all": "electron-builder -mwl",
|
"dist:all": "electron-builder --config electron-builder.config.js -mwl",
|
||||||
"download-tools": "node scripts/download-tools.js",
|
"download-tools": "node scripts/download-tools.js",
|
||||||
"bundle:markitdown": "node scripts/bundle-markitdown.js",
|
"bundle:markitdown": "node scripts/bundle-markitdown.js",
|
||||||
"generate-icons": "node scripts/generate-icons.js"
|
"generate-icons": "node scripts/generate-icons.js"
|
||||||
@@ -99,148 +99,5 @@
|
|||||||
"lodash.pick": "npm:lodash@^4.17.21",
|
"lodash.pick": "npm:lodash@^4.17.21",
|
||||||
"lodash-es": "^4.18.1",
|
"lodash-es": "^4.18.1",
|
||||||
"lodash": "^4.17.21"
|
"lodash": "^4.17.21"
|
||||||
},
|
|
||||||
"build": {
|
|
||||||
"appId": "com.concreteinfo.markdownconverter",
|
|
||||||
"productName": "MarkdownConverter",
|
|
||||||
"copyright": "Copyright (C) 2024-2025 ConcreteInfo",
|
|
||||||
"directories": {
|
|
||||||
"output": "dist"
|
|
||||||
},
|
|
||||||
"icon": "assets/icon",
|
|
||||||
"files": [
|
|
||||||
"src/**/*",
|
|
||||||
"assets/**/*",
|
|
||||||
"scripts/**/*",
|
|
||||||
"node_modules/**/*",
|
|
||||||
"package.json",
|
|
||||||
"THIRD-PARTY-NOTICES.md",
|
|
||||||
"SOURCES.md"
|
|
||||||
],
|
|
||||||
"asarUnpack": [
|
|
||||||
"node_modules/ffmpeg-static/**",
|
|
||||||
"node_modules/sharp/**",
|
|
||||||
"node_modules/@img/**",
|
|
||||||
"node_modules/@napi-rs/**",
|
|
||||||
"assets/fonts/**"
|
|
||||||
],
|
|
||||||
"extraFiles": [],
|
|
||||||
"fileAssociations": [
|
|
||||||
{
|
|
||||||
"ext": "md",
|
|
||||||
"name": "Markdown Document",
|
|
||||||
"description": "Markdown Document",
|
|
||||||
"mimeType": "text/markdown",
|
|
||||||
"role": "Editor"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ext": "markdown",
|
|
||||||
"name": "Markdown Document",
|
|
||||||
"description": "Markdown Document",
|
|
||||||
"mimeType": "text/markdown",
|
|
||||||
"role": "Editor"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ext": "pdf",
|
|
||||||
"name": "PDF Document",
|
|
||||||
"description": "PDF Document",
|
|
||||||
"mimeType": "application/pdf",
|
|
||||||
"role": "Editor"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"mac": {
|
|
||||||
"category": "public.app-category.productivity",
|
|
||||||
"identity": null,
|
|
||||||
"extraFiles": [
|
|
||||||
{
|
|
||||||
"from": "bin/darwin/pandoc",
|
|
||||||
"to": "bin/pandoc"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from": "bin/darwin/markitdown",
|
|
||||||
"to": "bin/markitdown"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"win": {
|
|
||||||
"target": [
|
|
||||||
{
|
|
||||||
"target": "nsis",
|
|
||||||
"arch": [
|
|
||||||
"x64"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"target": "portable",
|
|
||||||
"arch": [
|
|
||||||
"x64"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"target": "zip",
|
|
||||||
"arch": [
|
|
||||||
"x64"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"artifactName": "${productName}-${version}-${arch}.${ext}",
|
|
||||||
"requestedExecutionLevel": "asInvoker",
|
|
||||||
"legalTrademarks": "Copyright (C) 2024-2025 ConcreteInfo",
|
|
||||||
"verifyUpdateCodeSignature": false,
|
|
||||||
"signAndEditExecutable": false,
|
|
||||||
"extraFiles": [
|
|
||||||
{
|
|
||||||
"from": "bin/win32/pandoc.exe",
|
|
||||||
"to": "bin/pandoc.exe"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from": "bin/win32/markitdown.exe",
|
|
||||||
"to": "bin/markitdown.exe"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"nsis": {
|
|
||||||
"oneClick": false,
|
|
||||||
"perMachine": false,
|
|
||||||
"allowToChangeInstallationDirectory": true,
|
|
||||||
"displayLanguageSelector": true,
|
|
||||||
"createDesktopShortcut": true,
|
|
||||||
"createStartMenuShortcut": true,
|
|
||||||
"shortcutName": "MarkdownConverter",
|
|
||||||
"runAfterFinish": true,
|
|
||||||
"menuCategory": "Productivity",
|
|
||||||
"license": "LICENSE",
|
|
||||||
"warningsAsErrors": false,
|
|
||||||
"artifactName": "${productName}-Setup-${version}.${ext}",
|
|
||||||
"deleteAppDataOnUninstall": false,
|
|
||||||
"differentialPackage": true
|
|
||||||
},
|
|
||||||
"linux": {
|
|
||||||
"target": [
|
|
||||||
"deb",
|
|
||||||
"AppImage",
|
|
||||||
"snap"
|
|
||||||
],
|
|
||||||
"category": "Utility",
|
|
||||||
"maintainer": "ConcreteInfo <amit.wh@gmail.com>",
|
|
||||||
"extraFiles": [
|
|
||||||
{
|
|
||||||
"from": "bin/linux/pandoc",
|
|
||||||
"to": "bin/pandoc"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from": "bin/linux/markitdown",
|
|
||||||
"to": "bin/markitdown"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"deb": {
|
|
||||||
"depends": [
|
|
||||||
"imagemagick",
|
|
||||||
"libreoffice-common"
|
|
||||||
],
|
|
||||||
"description": "Professional Markdown editor and universal file converter",
|
|
||||||
"maintainer": "ConcreteInfo <amit.wh@gmail.com>"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ const PANDOC_VERSION = '3.9.0.2';
|
|||||||
*/
|
*/
|
||||||
const KNOWN_SHA256 = {
|
const KNOWN_SHA256 = {
|
||||||
'linux:pandoc': '7d124235998ecd3cdd9a463b1e5f6691a178b6461824c29a36170a0882f05597',
|
'linux:pandoc': '7d124235998ecd3cdd9a463b1e5f6691a178b6461824c29a36170a0882f05597',
|
||||||
|
'win32:pandoc.exe': 'e83f8354c0f507222b5684797b9c5ae766f03889785995d14aac27816ec456ba',
|
||||||
// Fill these from a trusted machine after the first download of each
|
// Fill these from a trusted machine after the first download of each
|
||||||
// platform (the script prints the computed hash):
|
// platform (the script prints the computed hash):
|
||||||
// 'win32:pandoc.exe': '…',
|
|
||||||
// 'darwin:pandoc': '…',
|
// 'darwin:pandoc': '…',
|
||||||
'fonts:FiraCode-Regular.ttf': '3c79d234a9161c790410ebb2a80de7efb7c15f581062c130e0fa78503ccdd0da',
|
'fonts:FiraCode-Regular.ttf': '3c79d234a9161c790410ebb2a80de7efb7c15f581062c130e0fa78503ccdd0da',
|
||||||
'fonts:FiraCode-Bold.ttf': '975f26779fac1029c2cbdac1e9fac7e9ddeec05e064675e4aac63bffa121742f',
|
'fonts:FiraCode-Bold.ttf': '975f26779fac1029c2cbdac1e9fac7e9ddeec05e064675e4aac63bffa121742f',
|
||||||
|
|||||||
+17
-1
@@ -27,11 +27,27 @@ if (process.platform === 'win32') {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directory of the bundled external tools (pandoc/markitdown) in a PACKAGED
|
||||||
|
* app. electron-builder extraFiles land next to the executable on Linux and
|
||||||
|
* Windows, and inside Contents/ on macOS — NOT in resources/bin (which is
|
||||||
|
* where the lookup incorrectly pointed before v4.7, making packaged builds
|
||||||
|
* silently fall back to system-installed tools).
|
||||||
|
*/
|
||||||
|
function bundledToolDir() {
|
||||||
|
if (process.platform === 'darwin') {
|
||||||
|
// resourcesPath = …/Contents/Resources → tools live in …/Contents/bin
|
||||||
|
return path.join(path.dirname(process.resourcesPath), 'bin');
|
||||||
|
}
|
||||||
|
// exePath = …/MarkdownConverter(.exe) → tools live in …/bin
|
||||||
|
return path.join(path.dirname(process.execPath), 'bin');
|
||||||
|
}
|
||||||
|
|
||||||
// Returns path to pandoc: bundled binary when packaged, dev bin or system fallback otherwise.
|
// Returns path to pandoc: bundled binary when packaged, dev bin or system fallback otherwise.
|
||||||
function getPandocPath() {
|
function getPandocPath() {
|
||||||
if (app.isPackaged) {
|
if (app.isPackaged) {
|
||||||
const ext = process.platform === 'win32' ? '.exe' : '';
|
const ext = process.platform === 'win32' ? '.exe' : '';
|
||||||
return path.join(process.resourcesPath, 'bin', `pandoc${ext}`);
|
return path.join(bundledToolDir(), `pandoc${ext}`);
|
||||||
}
|
}
|
||||||
// Development: prefer locally-downloaded binary in bin/<platform>/
|
// Development: prefer locally-downloaded binary in bin/<platform>/
|
||||||
const devBin = path.join(
|
const devBin = path.join(
|
||||||
|
|||||||
+15
-8
@@ -24,25 +24,32 @@ const MAX_OUTPUT_BUFFER = 20 * 1024 * 1024;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Path to the bundled markitdown binary (built by scripts/bundle-markitdown.js
|
* Path to the bundled markitdown binary (built by scripts/bundle-markitdown.js
|
||||||
* via PyInstaller), when the app ships one. Mirrors getPandocPath's layout:
|
* via PyInstaller), when the app ships one. Layout matches getPandocPath:
|
||||||
* dev: bin/<platform>/markitdown · packaged: <resourcesPath>/bin/markitdown.
|
* dev: bin/<platform>/markitdown · packaged: <app dir>/bin/markitdown (next
|
||||||
* Returns null when no bundle exists (PATH/python fallbacks apply).
|
* to the executable on Linux/Windows, Contents/bin on macOS — the same
|
||||||
|
* extraFiles destination). Returns null when absent (PATH/python fallbacks).
|
||||||
*/
|
*/
|
||||||
function getBundledMarkItDownPath() {
|
function getBundledMarkItDownPath() {
|
||||||
const pathUtil = require('path');
|
const pathUtil = require('path');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const exe = process.platform === 'win32' ? 'markitdown.exe' : 'markitdown';
|
const exe = process.platform === 'win32' ? 'markitdown.exe' : 'markitdown';
|
||||||
if (typeof process === 'object' && process.resourcesPath && !process.resourcesPath.includes('node_modules')) {
|
|
||||||
// Packaged (Electron) — resourcesPath only exists in a real app runtime
|
|
||||||
try {
|
try {
|
||||||
|
// Only meaningful under Electron; tests import this module under Node
|
||||||
const electron = require('electron');
|
const electron = require('electron');
|
||||||
if (electron.app?.isPackaged) {
|
if (electron.app?.isPackaged) {
|
||||||
const packaged = pathUtil.join(process.resourcesPath, 'bin', exe);
|
const base =
|
||||||
|
process.platform === 'darwin'
|
||||||
|
? pathUtil.dirname(electron.app.getPath('exe')) // …/Contents/MacOS
|
||||||
|
: pathUtil.dirname(process.execPath);
|
||||||
|
const packaged =
|
||||||
|
process.platform === 'darwin'
|
||||||
|
? pathUtil.join(base, '..', 'bin', exe) // …/Contents/bin
|
||||||
|
: pathUtil.join(base, 'bin', exe);
|
||||||
if (fs.existsSync(packaged)) return packaged;
|
if (fs.existsSync(packaged)) return packaged;
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
/* not running under Electron (tests) — fall through to dev layout */
|
/* not running under Electron (tests) — use the dev layout below */
|
||||||
}
|
|
||||||
}
|
}
|
||||||
const dev = pathUtil.join(__dirname, '..', '..', 'bin', process.platform, exe);
|
const dev = pathUtil.join(__dirname, '..', '..', 'bin', process.platform, exe);
|
||||||
return fs.existsSync(dev) ? dev : null;
|
return fs.existsSync(dev) ? dev : null;
|
||||||
|
|||||||
@@ -87,9 +87,18 @@ describe('Legal compliance artifacts', () => {
|
|||||||
expect(sources).toMatch(/https:\/\/ffmpeg\.org\/releases\//);
|
expect(sources).toMatch(/https:\/\/ffmpeg\.org\/releases\//);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('packaging includes the legal documents in build.files', () => {
|
test('packaging includes the legal documents in build files', () => {
|
||||||
|
// The build config lives in electron-builder.config.js (dynamic — it
|
||||||
|
// conditionally bundles the markitdown binary per platform)
|
||||||
|
const configSrc = fs.readFileSync(
|
||||||
|
path.join(rootDir, 'electron-builder.config.js'),
|
||||||
|
'utf-8'
|
||||||
|
);
|
||||||
|
expect(configSrc).toContain("'THIRD-PARTY-NOTICES.md'");
|
||||||
|
expect(configSrc).toContain("'SOURCES.md'");
|
||||||
|
expect(configSrc).toContain('third-party-licenses');
|
||||||
|
// And package.json must not carry a stale static build section anymore
|
||||||
const pkg = JSON.parse(fs.readFileSync(path.join(rootDir, 'package.json'), 'utf-8'));
|
const pkg = JSON.parse(fs.readFileSync(path.join(rootDir, 'package.json'), 'utf-8'));
|
||||||
expect(pkg.build.files).toContain('THIRD-PARTY-NOTICES.md');
|
expect(pkg.build).toBeUndefined();
|
||||||
expect(pkg.build.files).toContain('SOURCES.md');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -50,8 +50,11 @@ function listFilesRecursively(dir) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
test('sharp-linux-x64 ships its native binding', () => {
|
test('sharp-linux-x64 ships its native binding', () => {
|
||||||
const binding = path.join(UNPACKED_IMG_DIR, 'sharp-linux-x64', 'lib', 'sharp-linux-x64.node');
|
// sharp 0.35 names the binding with a version suffix
|
||||||
expect(fs.existsSync(binding)).toBe(true);
|
// (sharp-linux-x64-0.35.4.node); 0.34 used a bare name — accept both
|
||||||
|
const libDir = path.join(UNPACKED_IMG_DIR, 'sharp-linux-x64', 'lib');
|
||||||
|
const bindings = fs.readdirSync(libDir).filter((f) => /^sharp-linux-x64.*\.node$/.test(f));
|
||||||
|
expect(bindings.length).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('sharp-libvips-linux-x64 ships the bundled libvips shared libraries', () => {
|
test('sharp-libvips-linux-x64 ships the bundled libvips shared libraries', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user