-
-
Notifications
You must be signed in to change notification settings - Fork 197
/
Copy pathnode-modules-dest-copy.ts
118 lines (102 loc) · 4.92 KB
/
node-modules-dest-copy.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
///<reference path="../../.d.ts"/>
"use strict";
import fs = require("fs");
import path = require('path');
import semver = require("semver");
import util = require("util");
import shelljs = require("shelljs");
import {wrapBroccoliPlugin} from './broccoli-plugin-wrapper-factory';
import constants = require("./../../constants");
/**
* Intercepts each directory as it is copied to the destination tempdir,
* and tees a copy to the given path outside the tmp dir.
*/
export class DestCopy implements IBroccoliPlugin {
private dependencies: IDictionary<any> = null;
private devDependencies: IDictionary<any> = null;
constructor(private inputPath: string,
private cachePath: string,
private outputRoot: string,
private projectDir: string,
private platform: string,
private $fs: IFileSystem,
private $projectFilesManager: IProjectFilesManager,
private $pluginsService: IPluginsService) {
this.dependencies = Object.create(null);
this.devDependencies = this.getDevDependencies(projectDir);
}
public rebuildChangedDirectories(changedDirectories: string[], platform: string): void {
_.each(changedDirectories, changedDirectoryAbsolutePath => {
if(!this.devDependencies[path.basename(changedDirectoryAbsolutePath)]) {
let pathToPackageJson = path.join(changedDirectoryAbsolutePath, constants.PACKAGE_JSON_FILE_NAME);
let packageJsonFiles = fs.existsSync(pathToPackageJson) ? [pathToPackageJson] : [];
let nodeModulesFolderPath = path.join(changedDirectoryAbsolutePath, constants.NODE_MODULES_FOLDER_NAME);
packageJsonFiles = packageJsonFiles.concat(this.enumeratePackageJsonFilesSync(nodeModulesFolderPath));
_.each(packageJsonFiles, packageJsonFilePath => {
let fileContent = require(packageJsonFilePath);
if(!this.devDependencies[fileContent.name]) { // Don't flatten dev dependencies
let currentDependency = {
name: fileContent.name,
version: fileContent.version,
directory: path.dirname(packageJsonFilePath),
nativescript: fileContent.nativescript
};
let addedDependency = this.dependencies[currentDependency.name];
if (addedDependency) {
if (semver.gt(currentDependency.version, addedDependency.version)) {
let currentDependencyMajorVersion = semver.major(currentDependency.version);
let addedDependencyMajorVersion = semver.major(addedDependency.version);
let message = `The depedency located at ${addedDependency.directory} with version ${addedDependency.version} will be replaced with dependency located at ${currentDependency.directory} with version ${currentDependency.version}`;
let logger = $injector.resolve("$logger");
currentDependencyMajorVersion === addedDependencyMajorVersion ? logger.out(message) : logger.warn(message);
this.dependencies[currentDependency.name] = currentDependency;
}
} else {
this.dependencies[currentDependency.name] = currentDependency;
}
}
});
}
});
_.each(this.dependencies, dependency => {
shelljs.cp("-Rf", dependency.directory, this.outputRoot);
shelljs.rm("-rf", path.join(this.outputRoot, dependency.name, "node_modules"));
let isPlugin = !!dependency.nativescript;
if(isPlugin) {
this.$pluginsService.prepare(dependency).wait();
shelljs.rm("-rf", path.join(this.outputRoot, dependency.name, "platforms"));
}
});
}
public rebuild(treeDiff: IDiffResult): void {
this.rebuildChangedDirectories(treeDiff.changedDirectories, "");
// Cache input tree
let projectFilePath = path.join(this.projectDir, constants.PACKAGE_JSON_FILE_NAME);
let projectFileContent = require(projectFilePath);
projectFileContent[constants.NATIVESCRIPT_KEY_NAME][constants.NODE_MODULE_CACHE_PATH_KEY_NAME] = this.inputPath;
fs.writeFileSync(projectFilePath, JSON.stringify(projectFileContent, null, "\t"), { encoding: "utf8" });
}
private getDevDependencies(projectDir: string): IDictionary<any> {
let projectFilePath = path.join(projectDir, constants.PACKAGE_JSON_FILE_NAME);
let projectFileContent = require(projectFilePath);
return projectFileContent.devDependencies || {};
}
private enumeratePackageJsonFilesSync(nodeModulesDirectoryPath: string, foundFiles?: string[]): string[] {
foundFiles = foundFiles || [];
if(fs.existsSync(nodeModulesDirectoryPath)) {
let contents = fs.readdirSync(nodeModulesDirectoryPath);
for (let i = 0; i < contents.length; ++i) {
let packageJsonFilePath = path.join(nodeModulesDirectoryPath, contents[i], constants.PACKAGE_JSON_FILE_NAME);
if (fs.existsSync(packageJsonFilePath)) {
foundFiles.push(packageJsonFilePath);
}
var directoryPath = path.join(nodeModulesDirectoryPath, contents[i], constants.NODE_MODULES_FOLDER_NAME);
if (fs.existsSync(directoryPath)) {
this.enumeratePackageJsonFilesSync(directoryPath, foundFiles);
}
}
}
return foundFiles;
}
}
export default wrapBroccoliPlugin(DestCopy);