|
1 | | -import * as constants from "../../../lib/constants"; |
2 | | -import * as path from "path"; |
3 | 1 | import * as shelljs from "shelljs"; |
4 | 2 | import { TnsModulesCopy, NpmPluginPrepare } from "./node-modules-dest-copy"; |
5 | 3 | import { NodeModulesDependenciesBuilder } from "./node-modules-dependencies-builder"; |
6 | | -import { sleep, deferPromise } from "../../../lib/common/helpers"; |
7 | | - |
8 | | -let glob = require("glob"); |
9 | 4 |
|
10 | 5 | export class NodeModulesBuilder implements INodeModulesBuilder { |
11 | 6 | constructor(private $fs: IFileSystem, |
12 | 7 | private $injector: IInjector, |
13 | | - private $lockfile: ILockFile, |
14 | 8 | private $options: IOptions |
15 | 9 | ) { } |
16 | 10 |
|
17 | | - public async getChangedNodeModules(absoluteOutputPath: string, platform: string, projectData: IProjectData, lastModifiedTime?: Date): Promise<any> { |
18 | | - let projectDir = projectData.projectDir; |
19 | | - let isNodeModulesModified = false; |
20 | | - let nodeModulesPath = path.join(projectDir, constants.NODE_MODULES_FOLDER_NAME); |
21 | | - let nodeModules: any = {}; |
22 | | - |
23 | | - if (lastModifiedTime) { |
24 | | - let defer = deferPromise(); |
25 | | - |
26 | | - let match = new glob.Glob("node_modules/**", { |
27 | | - cwd: projectDir, |
28 | | - follow: true, |
29 | | - stat: true |
30 | | - }, (er: Error, files: string[]) => { |
31 | | - while (this.$lockfile.check()) { |
32 | | - sleep(10); |
33 | | - } |
34 | | - |
35 | | - this.$lockfile.lock(); |
36 | | - if (er) { |
37 | | - if (!defer.isResolved()) { |
38 | | - defer.reject(er); |
39 | | - } |
40 | | - |
41 | | - this.$lockfile.unlock(); |
42 | | - match.abort(); |
43 | | - return; |
44 | | - } |
45 | | - for (let i = 0, l = files.length; i < l; i++) { |
46 | | - let file = files[i], |
47 | | - resolvedPath = path.join(projectDir, file), |
48 | | - relativePath = path.relative(projectDir, resolvedPath); |
49 | | - let stat = match.statCache[resolvedPath] || match.statCache[relativePath]; |
50 | | - if (!stat) { |
51 | | - match.statCache[resolvedPath] = stat = this.$fs.getFsStats(resolvedPath); |
52 | | - } |
53 | | - |
54 | | - if (stat.mtime <= lastModifiedTime) { |
55 | | - continue; |
56 | | - } |
57 | | - if (file === constants.NODE_MODULES_FOLDER_NAME) { |
58 | | - isNodeModulesModified = true; |
59 | | - this.$lockfile.unlock(); |
60 | | - match.abort(); |
61 | | - if (!defer.isResolved()) { |
62 | | - defer.resolve(); |
63 | | - } |
64 | | - |
65 | | - return; |
66 | | - } |
67 | | - let rootModuleName = path.normalize(file).split(path.sep)[1]; |
68 | | - let rootModuleFullPath = path.join(nodeModulesPath, rootModuleName); |
69 | | - nodeModules[rootModuleFullPath] = rootModuleFullPath; |
70 | | - } |
71 | | - |
72 | | - this.$lockfile.unlock(); |
73 | | - }); |
74 | | - |
75 | | - match.on("end", () => { |
76 | | - if (!defer.isResolved()) { |
77 | | - let intervalId = setInterval(() => { |
78 | | - if (!this.$lockfile.check() || defer.isResolved()) { |
79 | | - if (!defer.isResolved()) { |
80 | | - defer.resolve(); |
81 | | - } |
82 | | - clearInterval(intervalId); |
83 | | - } |
84 | | - }, 100); |
85 | | - } |
86 | | - }); |
87 | | - |
88 | | - await defer.promise; |
89 | | - } |
90 | | - |
91 | | - if (isNodeModulesModified && this.$fs.exists(absoluteOutputPath)) { |
92 | | - let currentPreparedTnsModules = this.$fs.readDirectory(absoluteOutputPath); |
93 | | - let tnsModulesPath = path.join(projectDir, constants.NODE_MODULES_FOLDER_NAME, constants.TNS_CORE_MODULES_NAME); |
94 | | - let tnsModulesInApp = this.$fs.readDirectory(tnsModulesPath); |
95 | | - let modulesToDelete = _.difference(currentPreparedTnsModules, tnsModulesInApp); |
96 | | - _.each(modulesToDelete, moduleName => this.$fs.deleteDirectory(path.join(absoluteOutputPath, moduleName))); |
97 | | - } |
98 | | - |
99 | | - if (!lastModifiedTime || isNodeModulesModified) { |
100 | | - this.expandScopedModules(nodeModulesPath, nodeModules); |
101 | | - } |
102 | | - |
103 | | - return nodeModules; |
104 | | - } |
105 | | - |
106 | | - private expandScopedModules(nodeModulesPath: string, nodeModules: IStringDictionary): void { |
107 | | - let nodeModulesDirectories = this.$fs.exists(nodeModulesPath) ? this.$fs.readDirectory(nodeModulesPath) : []; |
108 | | - _.each(nodeModulesDirectories, nodeModuleDirectoryName => { |
109 | | - let isNpmScope = /^@/.test(nodeModuleDirectoryName); |
110 | | - let nodeModuleFullPath = path.join(nodeModulesPath, nodeModuleDirectoryName); |
111 | | - if (isNpmScope) { |
112 | | - this.expandScopedModules(nodeModuleFullPath, nodeModules); |
113 | | - } else { |
114 | | - nodeModules[nodeModuleFullPath] = nodeModuleFullPath; |
115 | | - } |
116 | | - }); |
117 | | - } |
118 | | - |
119 | 11 | public async prepareNodeModules(absoluteOutputPath: string, platform: string, lastModifiedTime: Date, projectData: IProjectData): Promise<void> { |
120 | 12 | if (!this.$fs.exists(absoluteOutputPath)) { |
121 | 13 | // Force copying if the destination doesn't exist. |
|
0 commit comments