mirror of
https://github.com/tutao/tutanota.git
synced 2025-12-08 06:09:50 +00:00
65 lines
2.5 KiB
JavaScript
65 lines
2.5 KiB
JavaScript
|
|
import fs from "node:fs/promises"
|
||
|
|
import path from "node:path"
|
||
|
|
import { spawnSync } from "node:child_process"
|
||
|
|
import { fileExists } from "./buildUtils.js"
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the version of electron used by the app (as in package.json).
|
||
|
|
* @returns Promise<{string}>
|
||
|
|
*/
|
||
|
|
export async function getElectronVersion(log = console.log.bind(console)) {
|
||
|
|
return await getInstalledModuleVersion("electron", log)
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the installed version of a module
|
||
|
|
* @param module {string}
|
||
|
|
* @returns Promise<{string}>
|
||
|
|
*/
|
||
|
|
export async function getInstalledModuleVersion(module, log) {
|
||
|
|
let json
|
||
|
|
const cachePath = "node_modules/.npm-deps-resolved"
|
||
|
|
if (await fileExists(cachePath)) {
|
||
|
|
// Look for node_modules in current directory
|
||
|
|
const content = await fs.readFile(cachePath, "utf8")
|
||
|
|
json = JSON.parse(content)
|
||
|
|
} else if (await fileExists(path.join("..", cachePath))) {
|
||
|
|
// Try to find node_modules in directory one level up (e.g. if we run tests). Should be probably more generic
|
||
|
|
const content = await fs.readFile(path.join("..", cachePath), "utf8")
|
||
|
|
json = JSON.parse(content)
|
||
|
|
} else {
|
||
|
|
console.log(`Using slow method to resolve dependency version. Add a postinstall script to dump 'npm list' into ${cachePath} to speed things up.`)
|
||
|
|
// npm list likes to error out for no reason so we just print a warning. If it really fails, we will see it.
|
||
|
|
// shell: true because otherwise Windows can't find npm.
|
||
|
|
const { stdout, stderr, status, error } = spawnSync("npm", ["list", module, "--json"], { shell: true })
|
||
|
|
if (status !== 0) {
|
||
|
|
log(`npm list is not happy about ${module}, but it doesn't mean anything`, status, stderr.toString(), error)
|
||
|
|
}
|
||
|
|
json = JSON.parse(stdout.toString().trim())
|
||
|
|
}
|
||
|
|
|
||
|
|
const version = findVersion(json, module)
|
||
|
|
if (version == null) {
|
||
|
|
throw new Error(`Could not find version of ${module}`)
|
||
|
|
}
|
||
|
|
return version
|
||
|
|
}
|
||
|
|
|
||
|
|
// Unfortunately `npm list` is garbage and instead of just giving you the info about package it will give you some subtree with the thing you are looking for
|
||
|
|
// buried deep beneath. So we try to find it manually by descending into each dependency.
|
||
|
|
// This surfaces in admin client when keytar is not our direct dependency but rather through the tutanota-3
|
||
|
|
function findVersion({ dependencies }, nodeModule) {
|
||
|
|
if (dependencies[nodeModule]) {
|
||
|
|
return dependencies[nodeModule].version
|
||
|
|
} else {
|
||
|
|
for (const [name, dep] of Object.entries(dependencies)) {
|
||
|
|
if ("dependencies" in dep) {
|
||
|
|
const found = findVersion(dep, nodeModule)
|
||
|
|
if (found) {
|
||
|
|
return found
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|