Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 0 additions & 90 deletions .yarn/patches/app-builder-lib-npm-24.13.3-86a66c0bf3.patch

This file was deleted.

186 changes: 186 additions & 0 deletions .yarn/patches/app-builder-lib-npm-26.8.1-e88d27929a.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
# This patch makes two changes:
# - Support yarn's "resolution" field while resolving dependencies (see https://github.com/laurent22/joplin/pull/15034#discussion_r3046971785).
# - On Windows, if an existing uninstaller fails, gives an option to continue with the installation
# despite the failure (https://github.com/laurent22/joplin/pull/11541).
#
diff --git a/out/node-module-collector/nodeModulesCollector.d.ts b/out/node-module-collector/nodeModulesCollector.d.ts
index 601ab15e1c0617eb5782372cbcf7d9854ae308b0..d01cd0fd786923112de84f9cbacf31180a6c7980 100644
--- a/out/node-module-collector/nodeModulesCollector.d.ts
+++ b/out/node-module-collector/nodeModulesCollector.d.ts
@@ -25,6 +25,7 @@ export declare abstract class NodeModulesCollector<ProdDepType extends Dependenc
*/
getNodeModules({ packageName }: {
packageName: string;
+ workspaceDir: string;
}): Promise<{
nodeModules: NodeModuleInfo[];
logSummary: ModuleManager["logSummary"];
diff --git a/out/node-module-collector/nodeModulesCollector.js b/out/node-module-collector/nodeModulesCollector.js
index 0956d2657279b06ff210e5008583b9c35b533d5f..62044f0ab215635aeb8a358f6e6c2fbcb8cdc502 100644
--- a/out/node-module-collector/nodeModulesCollector.js
+++ b/out/node-module-collector/nodeModulesCollector.js
@@ -45,8 +45,8 @@ class NodeModulesCollector {
* 5. Hoisting the dependencies to their final locations
* 6. Resolving and returning module information
*/
- async getNodeModules({ packageName }) {
- const tree = await this.getDependenciesTree(this.installOptions.manager);
+ async getNodeModules({ packageName, workspaceDir }) {
+ const tree = await this.getDependenciesTree(this.installOptions.manager, workspaceDir);
await this.collectAllDependencies(tree, packageName);
const realTree = this.getTreeFromWorkspaces(tree, packageName);
await this.extractProductionDependencyGraph(realTree, packageName);
@@ -64,7 +64,7 @@ class NodeModulesCollector {
* the output to a temporary file. Includes retry logic to handle transient failures such as
* incomplete JSON output or missing files. Will retry up to 1 time with exponential backoff.
*/
- async getDependenciesTree(pm) {
+ async getDependenciesTree(pm, _workspaceDir) {
const command = (0, packageManager_1.getPackageManagerCommand)(pm);
const args = this.getArgs();
const tempOutputFile = await this.tempDirManager.getTempFile({
diff --git a/out/node-module-collector/traversalNodeModulesCollector.js b/out/node-module-collector/traversalNodeModulesCollector.js
index 851c5427b676c0c8e65b7b63bcf8eadef68904a3..6391c1f3be447cf794ebc7bd5c00b46d34ef4adf 100644
--- a/out/node-module-collector/traversalNodeModulesCollector.js
+++ b/out/node-module-collector/traversalNodeModulesCollector.js
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
exports.TraversalNodeModulesCollector = void 0;
const builder_util_1 = require("builder-util");
const path = require("path");
+const fs = require("fs/promises");
+const semverValid = require('semver/functions/valid');
const moduleManager_1 = require("./moduleManager");
const nodeModulesCollector_1 = require("./nodeModulesCollector");
const packageManager_js_1 = require("./packageManager.js");
@@ -18,9 +20,9 @@ class TraversalNodeModulesCollector extends nodeModulesCollector_1.NodeModulesCo
getArgs() {
return [];
}
- getDependenciesTree(_pm) {
+ getDependenciesTree(_pm, workspaceDir) {
builder_util_1.log.info(null, "using manual traversal of node_modules to build dependency tree");
- return this.buildNodeModulesTreeManually(this.rootDir, undefined);
+ return this.buildNodeModulesTreeManually(this.rootDir, undefined, workspaceDir);
}
async collectAllDependencies(tree, appPackageName) {
for (const [packageKey, value] of Object.entries({ ...tree.dependencies, ...tree.optionalDependencies })) {
@@ -49,10 +51,40 @@ class TraversalNodeModulesCollector extends nodeModulesCollector_1.NodeModulesCo
* Builds a dependency tree using only package.json dependencies and optionalDependencies.
* This skips devDependencies and uses Node.js module resolution (require.resolve).
*/
- async buildNodeModulesTreeManually(baseDir, aliasName) {
+ async buildNodeModulesTreeManually(baseDir, aliasName, workspaceDir) {
// Track visited packages by their resolved path to prevent infinite loops
const visited = new Set();
const resolvedBaseDir = await this.cache.realPath[baseDir];
+
+ // JOPLIN CHANGE: Read the toplevel package.json file in the workspace:
+ const rootPackageJson = JSON.parse(await fs.readFile(path.join(workspaceDir, 'package.json')));
+
+ // Checks the "resolutions" field of the toplevel package.json
+ const handleResolutions = (depName, depVersion) => {
+ const resolutionKeys = [ depName, `${depName}@npm:${depVersion}` ];
+ for (const resolutionKey of resolutionKeys) {
+ if (rootPackageJson.resolutions && resolutionKey in rootPackageJson.resolutions) {
+ // Resolutions can take the form "patch:package@npm%3A1.2.3#./.yarn/patches/package-npm-4.5.6-d92bace04d.patch"
+ // where the "%3A" is a URL-encoded ":"
+ const resolvedTo = rootPackageJson.resolutions[resolutionKey].split('#')[0];
+ const patchMatch = resolvedTo.match(/^patch:[^@]+@npm%3A(.*)$/);
+
+ let resolution = null;
+ if (patchMatch) {
+ resolution = patchMatch[1];
+ } else if (semverValid(resolvedTo)) {
+ resolution = resolvedTo;
+ }
+
+ if (resolution) {
+ builder_util_1.log.info(`Resolving ${depName} to ${resolution}...`);
+ return resolution;
+ }
+ }
+ }
+ return depVersion;
+ };
+
/**
* Recursively builds dependency tree starting from a package directory.
* @param packageDir - The directory of the package to process
@@ -82,7 +112,9 @@ class TraversalNodeModulesCollector extends nodeModulesCollector_1.NodeModulesCo
visited.add(resolvedPackageDir);
const buildPackage = async (dependencies, nullHandler) => {
const builtPackages = {};
- for (const [depName, depVersion] of Object.entries(dependencies || {})) {
+ for (let [depName, depVersion] of Object.entries(dependencies || {})) {
+ depVersion = handleResolutions(depName, depVersion);
+
const pkg = await this.locatePackageWithVersion({ name: depName, version: depVersion, path: resolvedPackageDir });
const logFields = { parent: moduleName, dependency: depName, version: depVersion };
if (pkg == null) {
diff --git a/out/util/appFileCopier.js b/out/util/appFileCopier.js
index f762b47b85539eea2b38f6cf76692624a3b7e307..5975683046464777bb296b26f1ed46ae0c87770d 100644
--- a/out/util/appFileCopier.js
+++ b/out/util/appFileCopier.js
@@ -175,13 +175,16 @@ async function collectNodeModulesWithLogging(platformPackager) {
const packager = platformPackager.info;
const { tempDirManager, appDir, projectDir } = packager;
let deps = undefined;
- const searchDirectories = Array.from(new Set([appDir, projectDir, await packager.getWorkspaceRoot()])).filter((it) => (0, builder_util_1.isEmptyOrSpaces)(it) === false);
- const pmApproaches = [await packager.getPackageManager(), node_module_collector_1.PM.TRAVERSAL];
+ const workspaceDir = await packager.getWorkspaceRoot();
+ const searchDirectories = Array.from(new Set([appDir, projectDir, workspaceDir])).filter((it) => (0, builder_util_1.isEmptyOrSpaces)(it) === false);
+ // JOPLIN CHANGE: Always use the TRAVERSAL approach: The default yarn approach is unreliable:
+ const pmApproaches = [node_module_collector_1.PM.TRAVERSAL];
for (const pm of pmApproaches) {
for (const dir of searchDirectories) {
builder_util_1.log.info({ pm, searchDir: dir }, "searching for node modules");
const collector = (0, node_module_collector_1.getCollectorByPackageManager)(pm, dir, tempDirManager);
- deps = await collector.getNodeModules({ packageName: packager.metadata.name });
+ // JOPLIN CHANGE: Always pass "workspaceDir":
+ deps = await collector.getNodeModules({ packageName: packager.metadata.name, workspaceDir });
if (deps.nodeModules.length > 0) {
break;
}
diff --git a/templates/nsis/include/installUtil.nsh b/templates/nsis/include/installUtil.nsh
index 47367741632726ba0886ac516461dbe98b7aea58..e58d38b7b76276e39dd22864ce9754375e342a87 100644
--- a/templates/nsis/include/installUtil.nsh
+++ b/templates/nsis/include/installUtil.nsh
@@ -128,8 +128,9 @@ Function handleUninstallResult
${if} $R0 != 0
MessageBox MB_OK|MB_ICONEXCLAMATION "$(uninstallFailed): $R0"
DetailPrint `Uninstall was not successful. Uninstaller error code: $R0.`
- SetErrorLevel 2
- Quit
+ DetailPrint `Continuing anyway. See https://github.com/laurent22/joplin/pull/11612.`
+ # SetErrorLevel 2
+ # Quit
${endif}
FunctionEnd

@@ -216,11 +217,13 @@ Function uninstallOldVersion
IntOp $R5 $R5 + 1

${if} $R5 > 5
- MessageBox MB_RETRYCANCEL|MB_ICONEXCLAMATION "$(appCannotBeClosed)" /SD IDCANCEL IDRETRY OneMoreAttempt
- Return
+ MessageBox MB_RETRYCANCEL|MB_ICONEXCLAMATION "$(appCannotBeUninstalled)" /SD IDCANCEL IDRETRY ContinueWithoutUninstall
+ Abort ; Exit early
+ ContinueWithoutUninstall:
+ Return
${endIf}

- OneMoreAttempt:
+# OneMoreAttempt: ; Commented out because unused
ExecWait '"$uninstallerFileNameTemp" /S /KEEP_APP_DATA $0 _?=$installationDir' $R0
ifErrors TryInPlace CheckResult

diff --git a/templates/nsis/messages.yml b/templates/nsis/messages.yml
index 982e1b09e424c4f07ce7c1152fe5ce8b703f5f57..56074e4f7ee3bd69459087b380801b7dbbe55f68 100644
--- a/templates/nsis/messages.yml
+++ b/templates/nsis/messages.yml
@@ -238,3 +238,5 @@ uninstallFailed:
appClosing:
en: "Closing running ${PRODUCT_NAME}..."
cs: "Ukončuji aplikaci ${PRODUCT_NAME}..."
+appCannotBeUninstalled:
+ en: "The old version of ${PRODUCT_NAME} could not be removed. \nClick Retry to skip this step."
39 changes: 21 additions & 18 deletions Joplin_install_and_update.sh
Original file line number Diff line number Diff line change
Expand Up @@ -172,31 +172,34 @@ elif [[ $ARCHITECTURE =~ .*i386.*|.*i686.* ]]; then
fi

#-----------------------------------------------------
print "Checking dependencies..."
## Check if libfuse2 is present.
if [[ $(command -v ldconfig) ]]; then
LIBFUSE=$(ldconfig -p | grep "libfuse.so.2" || echo '')
fi
if [[ $LIBFUSE == "" ]]; then
LIBFUSE=$(find /lib /usr/lib /lib64 /usr/lib64 /usr/local/lib -name "libfuse.so.2" 2>/dev/null | grep "libfuse.so.2" || echo '')
fi
if [[ $LIBFUSE == "" ]]; then
print "${COLOR_RED}Error: Can't get libfuse2 on system, please install libfuse2${COLOR_RESET}"
print "See https://joplinapp.org/help/faq/#desktop-application-will-not-launch-on-linux and https://github.com/AppImage/AppImageKit/wiki/FUSE for more information"
exit 1
fi

#-----------------------------------------------------
# Download Joplin
#-----------------------------------------------------

# Get the latest version to download
if [[ "$INCLUDE_PRE_RELEASE" == true ]]; then
RELEASE_VERSION=$($DL - "https://api.github.com/repos/laurent22/joplin/releases" | grep -Po '"tag_name": ?"v\K.*?(?=")' | sort -rV | head -1)
else
RELEASE_VERSION=$($DL - "https://api.github.com/repos/laurent22/joplin/releases/latest" | grep -Po '"tag_name": ?"v\K.*?(?=")')
fi

#-----------------------------------------------------
print "Checking dependencies..."
## Check for libfuse2 for Joplin versions lesser than 3.6.9, which transitioned to a new AppImage runtime without libfuse2 dependency
if [[ $(compareVersions "$RELEASE_VERSION" "3.6.8") -le 0 ]]; then
if [[ $(command -v ldconfig) ]]; then
LIBFUSE=$(ldconfig -p | grep "libfuse.so.2" || echo '')
fi
if [[ $LIBFUSE == "" ]]; then
LIBFUSE=$(find /lib /usr/lib /lib64 /usr/lib64 /usr/local/lib -name "libfuse.so.2" 2>/dev/null | grep "libfuse.so.2" || echo '')
fi
if [[ $LIBFUSE == "" ]]; then
print "${COLOR_RED}Error: Can't get libfuse2 on system, please install libfuse2${COLOR_RESET}"
print "See https://joplinapp.org/help/faq/#desktop-application-will-not-launch-on-linux and https://github.com/AppImage/AppImageKit/wiki/FUSE for more information"
exit 1
fi
fi
Comment thread
personalizedrefrigerator marked this conversation as resolved.

#-----------------------------------------------------
# Download Joplin
#-----------------------------------------------------

# Check if it's in the latest version
if [[ -e "${INSTALL_DIR}/VERSION" ]]; then
CURRENT_VERSION=$(< "${INSTALL_DIR}/VERSION")
Expand Down
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,6 @@
"pdfjs-dist": "patch:pdfjs-dist@npm%3A3.11.174#./.yarn/patches/pdfjs-dist-npm-3.11.174-67f2fee6d6.patch",
"chokidar@^2.0.0": "3.5.3",
"rn-fetch-blob@0.12.0": "patch:rn-fetch-blob@npm%3A0.12.0#./.yarn/patches/rn-fetch-blob-npm-0.12.0-cf02e3c544.patch",
"app-builder-lib@26.0.0-alpha.7": "patch:app-builder-lib@npm%3A26.0.0-alpha.7#./.yarn/patches/app-builder-lib-npm-26.0.0-alpha.7-e1b3dca119.patch",
"app-builder-lib@24.13.3": "patch:app-builder-lib@npm%3A24.13.3#./.yarn/patches/app-builder-lib-npm-24.13.3-86a66c0bf3.patch",
"react-native-sqlite-storage@6.0.1": "patch:react-native-sqlite-storage@npm%3A6.0.1#./.yarn/patches/react-native-sqlite-storage-npm-6.0.1-8369d747bd.patch",
"react-native-paper@5.13.1": "patch:react-native-paper@npm%3A5.13.1#./.yarn/patches/react-native-paper-npm-5.13.1-f153e542e2.patch",
"react-native-popup-menu@0.17.0": "patch:react-native-popup-menu@npm%3A0.17.0#./.yarn/patches/react-native-popup-menu-npm-0.17.0-8b745d88dd.patch",
Expand All @@ -126,6 +124,7 @@
"depd@npm:2.0.0": "patch:depd@npm%3A2.0.0#~/.yarn/patches/depd-npm-2.0.0-b6c51a4b43.patch",
"depd@npm:^1.1.2": "patch:depd@npm%3A2.0.0#~/.yarn/patches/depd-npm-2.0.0-b6c51a4b43.patch",
"depd@npm:^1.1.0": "patch:depd@npm%3A2.0.0#~/.yarn/patches/depd-npm-2.0.0-b6c51a4b43.patch",
"formidable@npm:^2.0.1": "patch:formidable@npm%3A2.1.2#~/.yarn/patches/formidable-npm-2.1.2-40ba18d67f.patch"
"formidable@npm:^2.0.1": "patch:formidable@npm%3A2.1.2#~/.yarn/patches/formidable-npm-2.1.2-40ba18d67f.patch",
"app-builder-lib@npm:26.8.1": "patch:app-builder-lib@npm%3A26.8.1#~/.yarn/patches/app-builder-lib-npm-26.8.1-e88d27929a.patch"
}
}
Loading
Loading