Skip to content

Commit 503da26

Browse files
authored
feat: update app-builder-bin to 5.0-alpha release (#8190)
1 parent 48c5953 commit 503da26

File tree

9 files changed

+283
-122
lines changed

9 files changed

+283
-122
lines changed

.changeset/brave-rats-tap.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"app-builder-lib": minor
3+
"builder-util": minor
4+
---
5+
6+
feat: update app-builder-bin to 5.0-alpha release

packages/app-builder-lib/src/packager.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { ProtonFramework } from "./ProtonFramework"
2121
import { computeArchToTargetNamesMap, createTargets, NoOpTarget } from "./targets/targetFactory"
2222
import { computeDefaultAppDirectory, getConfig, validateConfiguration } from "./util/config"
2323
import { expandMacro } from "./util/macroExpander"
24-
import { createLazyProductionDeps, NodeModuleDirInfo } from "./util/packageDependencies"
24+
import { createLazyProductionDeps, NodeModuleDirInfo, NodeModuleInfo } from "./util/packageDependencies"
2525
import { checkMetadata, readPackageJson } from "./util/packageMetadata"
2626
import { getRepositoryInfo } from "./util/repositoryInfo"
2727
import { installOrRebuild, nodeGypRebuild } from "./util/yarn"
@@ -119,7 +119,7 @@ export class Packager {
119119

120120
private nodeDependencyInfo = new Map<string, Lazy<Array<any>>>()
121121

122-
getNodeDependencyInfo(platform: Platform | null): Lazy<Array<NodeModuleDirInfo>> {
122+
getNodeDependencyInfo(platform: Platform | null): Lazy<Array<NodeModuleInfo | NodeModuleDirInfo>> {
123123
let key = ""
124124
let excludedDependencies: Array<string> | null = null
125125
if (platform != null && this.framework.getExcludedDependencies != null) {
@@ -529,7 +529,7 @@ export class Packager {
529529
frameworkInfo,
530530
platform: platform.nodeName,
531531
arch: Arch[arch],
532-
productionDeps: this.getNodeDependencyInfo(null),
532+
productionDeps: this.getNodeDependencyInfo(null) as Lazy<Array<NodeModuleDirInfo>>,
533533
})
534534
}
535535
}

packages/app-builder-lib/src/util/NodeModuleCopyHelper.ts

Lines changed: 78 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { excludedNames, FileMatcher } from "../fileMatcher"
66
import { Packager } from "../packager"
77
import { resolveFunction } from "../platformPackager"
88
import { FileCopyHelper } from "./AppFileWalker"
9+
import { NodeModuleInfo } from "./packageDependencies"
910

1011
const excludedFiles = new Set(
1112
[".DS_Store", "node_modules" /* already in the queue */, "CHANGELOG.md", "ChangeLog", "changelog.md", "Changelog.md", "Changelog", "binding.gyp", ".npmignore"].concat(
@@ -37,108 +38,107 @@ export class NodeModuleCopyHelper extends FileCopyHelper {
3738
super(matcher, matcher.isEmpty() ? null : matcher.createFilter(), packager)
3839
}
3940

40-
async collectNodeModules(baseDir: string, moduleNames: Iterable<string>, nodeModuleExcludedExts: Array<string>): Promise<Array<string>> {
41+
async collectNodeModules(moduleInfo: NodeModuleInfo, nodeModuleExcludedExts: Array<string>): Promise<Array<string>> {
4142
const filter = this.filter
4243
const metadata = this.metadata
4344

4445
const onNodeModuleFile = await resolveFunction(this.packager.appInfo.type, this.packager.config.onNodeModuleFile, "onNodeModuleFile")
4546

4647
const result: Array<string> = []
4748
const queue: Array<string> = []
48-
for (const moduleName of moduleNames) {
49-
const tmpPath = baseDir + path.sep + moduleName
50-
queue.length = 1
51-
// The path should be corrected in Windows that when the moduleName is Scoped packages named.
52-
const depPath = path.normalize(tmpPath)
53-
queue[0] = depPath
54-
55-
while (queue.length > 0) {
56-
const dirPath = queue.pop()!
57-
58-
const childNames = await readdir(dirPath)
59-
childNames.sort()
60-
61-
const isTopLevel = dirPath === depPath
62-
const dirs: Array<string> = []
63-
// our handler is async, but we should add sorted files, so, we add file to result not in the mapper, but after map
64-
const sortedFilePaths = await BluebirdPromise.map(
65-
childNames,
66-
name => {
67-
const filePath = dirPath + path.sep + name
68-
69-
const forceIncluded = onNodeModuleFile != null && !!onNodeModuleFile(filePath)
70-
71-
if (excludedFiles.has(name) || name.startsWith("._")) {
72-
return null
73-
}
74-
75-
if (!forceIncluded) {
76-
for (const ext of nodeModuleExcludedExts) {
77-
if (name.endsWith(ext)) {
78-
return null
79-
}
80-
}
49+
const tmpPath = moduleInfo.dir
50+
const moduleName = moduleInfo.name
51+
queue.length = 1
52+
// The path should be corrected in Windows that when the moduleName is Scoped packages named.
53+
const depPath = path.normalize(tmpPath)
54+
queue[0] = depPath
55+
56+
while (queue.length > 0) {
57+
const dirPath = queue.pop()!
58+
59+
const childNames = await readdir(dirPath)
60+
childNames.sort()
61+
62+
const isTopLevel = dirPath === depPath
63+
const dirs: Array<string> = []
64+
// our handler is async, but we should add sorted files, so, we add file to result not in the mapper, but after map
65+
const sortedFilePaths = await BluebirdPromise.map(
66+
childNames,
67+
name => {
68+
const filePath = dirPath + path.sep + name
69+
70+
const forceIncluded = onNodeModuleFile != null && !!onNodeModuleFile(filePath)
71+
72+
if (excludedFiles.has(name) || name.startsWith("._")) {
73+
return null
74+
}
8175

82-
// noinspection SpellCheckingInspection
83-
if (isTopLevel && (topLevelExcludedFiles.has(name) || (moduleName === "libui-node" && (name === "build" || name === "docs" || name === "src")))) {
76+
if (!forceIncluded) {
77+
for (const ext of nodeModuleExcludedExts) {
78+
if (name.endsWith(ext)) {
8479
return null
8580
}
81+
}
8682

87-
if (dirPath.endsWith("build")) {
88-
if (name === "gyp-mac-tool" || name === "Makefile" || name.endsWith(".mk") || name.endsWith(".gypi") || name.endsWith(".Makefile")) {
89-
return null
90-
}
91-
} else if (dirPath.endsWith("Release") && (name === ".deps" || name === "obj.target")) {
92-
return null
93-
} else if (name === "src" && (dirPath.endsWith("keytar") || dirPath.endsWith("keytar-prebuild"))) {
94-
return null
95-
} else if (dirPath.endsWith("lzma-native") && (name === "build" || name === "deps")) {
96-
return null
97-
}
83+
// noinspection SpellCheckingInspection
84+
if (isTopLevel && (topLevelExcludedFiles.has(name) || (moduleName === "libui-node" && (name === "build" || name === "docs" || name === "src")))) {
85+
return null
9886
}
9987

100-
return lstat(filePath).then(stat => {
101-
if (filter != null && !filter(filePath, stat)) {
88+
if (dirPath.endsWith("build")) {
89+
if (name === "gyp-mac-tool" || name === "Makefile" || name.endsWith(".mk") || name.endsWith(".gypi") || name.endsWith(".Makefile")) {
10290
return null
10391
}
92+
} else if (dirPath.endsWith("Release") && (name === ".deps" || name === "obj.target")) {
93+
return null
94+
} else if (name === "src" && (dirPath.endsWith("keytar") || dirPath.endsWith("keytar-prebuild"))) {
95+
return null
96+
} else if (dirPath.endsWith("lzma-native") && (name === "build" || name === "deps")) {
97+
return null
98+
}
99+
}
104100

105-
if (!stat.isDirectory()) {
106-
metadata.set(filePath, stat)
101+
return lstat(filePath).then(stat => {
102+
if (filter != null && !filter(filePath, stat)) {
103+
return null
104+
}
105+
106+
if (!stat.isDirectory()) {
107+
metadata.set(filePath, stat)
108+
}
109+
const consumerResult = this.handleFile(filePath, dirPath, stat)
110+
if (consumerResult == null) {
111+
if (stat.isDirectory()) {
112+
dirs.push(name)
113+
return null
114+
} else {
115+
return filePath
107116
}
108-
const consumerResult = this.handleFile(filePath, dirPath, stat)
109-
if (consumerResult == null) {
110-
if (stat.isDirectory()) {
117+
} else {
118+
return consumerResult.then(it => {
119+
// asarUtil can return modified stat (symlink handling)
120+
if ((it == null ? stat : it).isDirectory()) {
111121
dirs.push(name)
112122
return null
113123
} else {
114124
return filePath
115125
}
116-
} else {
117-
return consumerResult.then(it => {
118-
// asarUtil can return modified stat (symlink handling)
119-
if ((it == null ? stat : it).isDirectory()) {
120-
dirs.push(name)
121-
return null
122-
} else {
123-
return filePath
124-
}
125-
})
126-
}
127-
})
128-
},
129-
CONCURRENCY
130-
)
131-
132-
for (const child of sortedFilePaths) {
133-
if (child != null) {
134-
result.push(child)
135-
}
126+
})
127+
}
128+
})
129+
},
130+
CONCURRENCY
131+
)
132+
133+
for (const child of sortedFilePaths) {
134+
if (child != null) {
135+
result.push(child)
136136
}
137+
}
137138

138-
dirs.sort()
139-
for (const child of dirs) {
140-
queue.push(dirPath + path.sep + child)
141-
}
139+
dirs.sort()
140+
for (const child of dirs) {
141+
queue.push(dirPath + path.sep + child)
142142
}
143143
}
144144
return result

packages/app-builder-lib/src/util/appFileCopier.ts

Lines changed: 49 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,37 @@ import { Packager } from "../packager"
1313
import { PlatformPackager } from "../platformPackager"
1414
import { AppFileWalker } from "./AppFileWalker"
1515
import { NodeModuleCopyHelper } from "./NodeModuleCopyHelper"
16+
import { NodeModuleInfo } from "./packageDependencies"
1617

1718
const BOWER_COMPONENTS_PATTERN = `${path.sep}bower_components${path.sep}`
1819
/** @internal */
1920
export const ELECTRON_COMPILE_SHIM_FILENAME = "__shim.js"
2021

22+
function extractPathAfterLastNodeModules(src: string, file: string) {
23+
const srcComponents = src.split(path.sep)
24+
const lastNodeModulesIndex = srcComponents.lastIndexOf("node_modules")
25+
26+
if (lastNodeModulesIndex === -1 || lastNodeModulesIndex === srcComponents.length - 1) {
27+
return ""
28+
}
29+
30+
const pathAfterNodeModules = srcComponents.slice(lastNodeModulesIndex + 1).join(path.sep)
31+
32+
const matchIndex = file.indexOf(pathAfterNodeModules)
33+
34+
if (matchIndex === -1) {
35+
return ""
36+
}
37+
38+
const remainingPathStartIndex = matchIndex + pathAfterNodeModules.length
39+
if (remainingPathStartIndex >= file.length) {
40+
return ""
41+
}
42+
43+
const remainingPath = file.substring(remainingPathStartIndex).trim()
44+
return remainingPath.startsWith(path.sep) ? remainingPath.substring(1) : remainingPath
45+
}
46+
2147
export function getDestinationPath(file: string, fileSet: ResolvedFileSet) {
2248
if (file === fileSet.src) {
2349
return fileSet.destination
@@ -27,17 +53,8 @@ export function getDestinationPath(file: string, fileSet: ResolvedFileSet) {
2753
if (file.length > src.length && file.startsWith(src) && file[src.length] === path.sep) {
2854
return dest + file.substring(src.length)
2955
} else {
30-
// hoisted node_modules
31-
// not lastIndexOf, to ensure that nested module (top-level module depends on) copied to parent node_modules, not to top-level directory
32-
// project https://github.com/angexis/punchcontrol/commit/cf929aba55c40d0d8901c54df7945e1d001ce022
33-
let index = file.indexOf(NODE_MODULES_PATTERN)
34-
if (index < 0 && file.endsWith(`${path.sep}node_modules`)) {
35-
index = file.length - 13
36-
}
37-
if (index < 0) {
38-
throw new Error(`File "${file}" not under the source directory "${fileSet.src}"`)
39-
}
40-
return dest + file.substring(index)
56+
const e = extractPathAfterLastNodeModules(src, file)
57+
return path.join(dest, e)
4158
}
4259
}
4360
}
@@ -191,25 +208,38 @@ function validateFileSet(fileSet: ResolvedFileSet): ResolvedFileSet {
191208

192209
/** @internal */
193210
export async function computeNodeModuleFileSets(platformPackager: PlatformPackager<any>, mainMatcher: FileMatcher): Promise<Array<ResolvedFileSet>> {
194-
const deps = await platformPackager.info.getNodeDependencyInfo(platformPackager.platform).value
211+
const deps = (await platformPackager.info.getNodeDependencyInfo(platformPackager.platform).value) as Array<NodeModuleInfo>
212+
195213
const nodeModuleExcludedExts = getNodeModuleExcludedExts(platformPackager)
196214
// serial execution because copyNodeModules is concurrent and so, no need to increase queue/pressure
197215
const result = new Array<ResolvedFileSet>()
198216
let index = 0
199217
for (const info of deps) {
200-
const source = info.dir
218+
const source = platformPackager.info.appDir + path.sep + "node_modules" + path.sep + info.name
219+
// const source = platformPackager.info.appDir
201220
const destination = getDestinationPath(source, { src: mainMatcher.from, destination: mainMatcher.to, files: [], metadata: null as any })
202221

203222
// use main matcher patterns, so, user can exclude some files in such hoisted node modules
204223
// source here includes node_modules, but pattern base should be without because users expect that pattern "!node_modules/loot-core/src{,/**/*}" will work
205-
const matcher = new FileMatcher(path.dirname(source), destination, mainMatcher.macroExpander, mainMatcher.patterns)
224+
const matcher = new FileMatcher(path.dirname(platformPackager.info.appDir + path.sep + "node_modules"), destination, mainMatcher.macroExpander, mainMatcher.patterns)
206225
const copier = new NodeModuleCopyHelper(matcher, platformPackager.info)
207-
const files = await copier.collectNodeModules(
208-
source,
209-
info.deps.map(it => it.name),
210-
nodeModuleExcludedExts
211-
)
226+
const files = await copier.collectNodeModules(info, nodeModuleExcludedExts)
212227
result[index++] = validateFileSet({ src: source, destination, files, metadata: copier.metadata })
228+
229+
if (info.conflictDependency) {
230+
for (const dep of info.conflictDependency) {
231+
const source = platformPackager.info.appDir + path.sep + "node_modules" + path.sep + info.name + path.sep + "node_modules" + path.sep + dep.name
232+
const destination = getDestinationPath(source, { src: mainMatcher.from, destination: mainMatcher.to, files: [], metadata: null as any })
233+
const matcher = new FileMatcher(
234+
path.dirname(platformPackager.info.appDir + path.sep + "node_modules" + path.sep + info.name + path.sep + "node_modules"),
235+
destination,
236+
mainMatcher.macroExpander,
237+
mainMatcher.patterns
238+
)
239+
const copier = new NodeModuleCopyHelper(matcher, platformPackager.info)
240+
result[index++] = validateFileSet({ src: source, destination, files: await copier.collectNodeModules(dep, nodeModuleExcludedExts), metadata: copier.metadata })
241+
}
242+
}
213243
}
214244
return result
215245
}

packages/app-builder-lib/src/util/packageDependencies.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { executeAppBuilderAsJson } from "./appBuilder"
33

44
export function createLazyProductionDeps(projectDir: string, excludedDependencies: Array<string> | null) {
55
return new Lazy(async () => {
6-
const args = ["node-dep-tree", "--dir", projectDir]
6+
const args = ["node-dep-tree", "--flatten", "--dir", projectDir]
77
if (excludedDependencies != null) {
88
for (const name of excludedDependencies) {
99
args.push("--exclude-dep", name)
@@ -20,4 +20,7 @@ export interface NodeModuleDirInfo {
2020

2121
export interface NodeModuleInfo {
2222
readonly name: string
23+
readonly version: string
24+
readonly dir: string
25+
readonly conflictDependency: Array<NodeModuleInfo>
2326
}

packages/builder-util/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"dependencies": {
1818
"7zip-bin": "~5.2.0",
1919
"@types/debug": "^4.1.6",
20-
"app-builder-bin": "4.0.0",
20+
"app-builder-bin": "v5.0.0-alpha.3",
2121
"bluebird-lst": "^1.0.9",
2222
"builder-util-runtime": "workspace:*",
2323
"chalk": "^4.1.2",

0 commit comments

Comments
 (0)