Skip to content

Commit 47712e6

Browse files
committed
fix: detecting workspace root for calculating whether a relative file is within the project directory due to monorepo workspaces having process.cwd() returning the subpackage instead of monorepo root
1 parent 2d014a8 commit 47712e6

File tree

5 files changed

+56
-3
lines changed

5 files changed

+56
-3
lines changed

.changeset/stupid-lobsters-own.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"app-builder-lib": patch
3+
---
4+
5+
fix: detecting workspace root for calculating whether a relative file is within the project directory due to monorepo workspaces having `process.cwd()` returning the subpackage instead of monorepo root

packages/app-builder-lib/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
"dotenv-expand": "^11.0.6",
6767
"ejs": "^3.1.8",
6868
"electron-publish": "workspace:*",
69+
"find-up": "^5.0.0",
6970
"fs-extra": "^10.1.0",
7071
"hosted-git-info": "^4.1.0",
7172
"isbinaryfile": "^5.0.0",
@@ -104,6 +105,7 @@
104105
"@babel/preset-react": "7.24.7",
105106
"@types/debug": "4.1.7",
106107
"@types/ejs": "3.1.0",
108+
"@types/find-up": "^4.0.2",
107109
"@types/hosted-git-info": "3.0.2",
108110
"@types/js-yaml": "4.0.3",
109111
"@types/plist": "3.0.5",

packages/app-builder-lib/src/asar/asarUtil.ts

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { PlatformPackager } from "../platformPackager"
99
import { ResolvedFileSet, getDestinationPath } from "../util/appFileCopier"
1010
import { detectUnpackedDirs } from "./unpackDetector"
1111
import { Readable } from "stream"
12+
import * as findUp from "find-up"
13+
import { readdir } from "fs/promises"
1214

1315
/** @internal */
1416
export class AsarPackager {
@@ -143,8 +145,9 @@ export class AsarPackager {
143145
return { path: destination, streamGenerator, unpacked, type: "file", stat: { mode: stat.mode, size } }
144146
}
145147

148+
const rootDir = (await findWorkspaceRoot(fileSet.src)) ?? fileSet.src
146149
const realPathFile = await fs.realpath(file)
147-
const realPathRelative = path.relative(fileSet.src, realPathFile)
150+
const realPathRelative = path.relative(rootDir, realPathFile)
148151
const isOutsidePackage = realPathRelative.startsWith("..")
149152
if (isOutsidePackage) {
150153
log.error({ source: log.filePath(file), realPathFile: log.filePath(realPathFile) }, `unable to copy, file is symlinked outside the package`)
@@ -159,7 +162,7 @@ export class AsarPackager {
159162
}
160163

161164
// not a symlink, stream directly
162-
if (file === realPathFile) {
165+
if (!stat.isSymbolicLink()) {
163166
return {
164167
...config,
165168
type: "file",
@@ -231,3 +234,33 @@ export class AsarPackager {
231234
}
232235
}
233236
}
237+
238+
export async function findWorkspaceRoot(startDir: string): Promise<string | undefined> {
239+
const packageJson = "package.json"
240+
const WORKSPACE_MARKERS = ["pnpm-workspace.yaml", "lerna.json", "nx.json", "turbo.json", ".yarnrc.yml", packageJson]
241+
// Use findUp to search for workspace markers in parent directories
242+
const file = await findUp(
243+
async directory => {
244+
const dirContents = await readdir(directory)
245+
const pkgJsonPath = path.join(directory, packageJson)
246+
247+
for (const filenameMarker of WORKSPACE_MARKERS) {
248+
if (dirContents.includes(filenameMarker)) {
249+
if (filenameMarker === packageJson) {
250+
const rootWorkspaceConfigPath = await fs
251+
.readJson(pkgJsonPath)
252+
.then(pkg => (pkg.workspaces || pkg.pnpm || pkg.workspaces?.packages ? pkgJsonPath : undefined))
253+
.catch(() => undefined) // ignore invalid package.json
254+
if (rootWorkspaceConfigPath) {
255+
return rootWorkspaceConfigPath
256+
}
257+
}
258+
return path.join(directory, filenameMarker)
259+
}
260+
}
261+
return dirContents.includes(".git") ? findUp.stop : undefined // stop searching if we hit a .git root directory
262+
},
263+
{ cwd: startDir }
264+
)
265+
return file ? path.dirname(file) : undefined
266+
}

packages/app-builder-lib/src/node-module-collector/yarnNodeModulesCollector.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,5 @@ export class YarnNodeModulesCollector extends NpmNodeModulesCollector {
66
super(rootDir)
77
}
88

9-
// note: do not override instance-var `pmCommand`. We explicitly use npm for the json payload
109
public readonly installOptions = { manager: PM.YARN, lockfile: "yarn.lock" }
1110
}

pnpm-lock.yaml

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)