Skip to content

Commit 39863a4

Browse files
Fatme HavaluovaFatme Havaluova
Fatme Havaluova
authored and
Fatme Havaluova
committed
Fix symlinks that are added to output package and points to not existing location
1 parent 78df478 commit 39863a4

File tree

5 files changed

+81
-47
lines changed

5 files changed

+81
-47
lines changed

lib/services/platform-service.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -148,13 +148,17 @@ export class PlatformService implements IPlatformService {
148148
platform = platform.toLowerCase();
149149

150150
var platformData = this.$platformsData.getPlatformData(platform);
151+
let appDestinationDirectoryPath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME);
152+
let lastModifiedTime = this.$fs.exists(appDestinationDirectoryPath).wait() ?
153+
this.$fs.getFsStats(appDestinationDirectoryPath).wait().mtime : null;
151154

152155
// Copy app folder to native project
156+
this.$fs.ensureDirectoryExists(appDestinationDirectoryPath).wait();
153157
var appSourceDirectoryPath = path.join(this.$projectData.projectDir, constants.APP_FOLDER_NAME);
154-
158+
155159
// Delete the destination app in order to prevent EEXIST errors when symlinks are used.
156160
this.$fs.deleteDirectory(path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME)).wait();
157-
shell.cp("-R", appSourceDirectoryPath, platformData.appDestinationDirectoryPath);
161+
shell.cp("-R", appSourceDirectoryPath, platformData.appDestinationDirectoryPath);
158162

159163
// Copy App_Resources to project root folder
160164
this.$fs.ensureDirectoryExists(platformData.appResourcesDestinationDirectoryPath).wait(); // Should be deleted
@@ -182,7 +186,7 @@ export class PlatformService implements IPlatformService {
182186
// Process node_modules folder
183187
this.$pluginsService.ensureAllDependenciesAreInstalled().wait();
184188
var tnsModulesDestinationPath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME, PlatformService.TNS_MODULES_FOLDER_NAME);
185-
this.$broccoliBuilder.prepareNodeModules(tnsModulesDestinationPath, this.$projectData.projectDir).wait();
189+
this.$broccoliBuilder.prepareNodeModules(tnsModulesDestinationPath, this.$projectData.projectDir, lastModifiedTime).wait();
186190

187191
this.$logger.out("Project successfully prepared");
188192
}).future<void>()();

lib/tools/broccoli/broccoli.d.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ interface BroccoliNode {
152152
}
153153

154154
interface IBroccoliBuilder {
155-
prepareNodeModules(outputPath: string, projectDir: string): IFuture<void>;
155+
prepareNodeModules(outputPath: string, projectDir: string, lastModifiedTime?: any): IFuture<void>;
156156
}
157157

158158
interface IDiffResult {
@@ -162,6 +162,7 @@ interface IDiffResult {
162162

163163
interface IBroccoliPlugin {
164164
rebuild(diff: IDiffResult): any;
165+
rebuildChangedDirectories?(changedDirectories: string[]): void;
165166
cleanup? () : void;
166167
}
167168

lib/tools/broccoli/builder.ts

+50-14
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,65 @@ let broccoli = require('broccoli');
55
let path = require('path');
66
import Future = require("fibers/future");
77
import {TreeDiffer} from './tree-differ';
8-
import destCopy = require('./node-modules-dest-copy');
8+
import destCopyLib = require('./node-modules-dest-copy');
9+
10+
var gulp = require("gulp");
11+
var vinylFilterSince = require('vinyl-filter-since')
12+
var through = require("through2");
913

1014
export class Builder implements IBroccoliBuilder {
15+
private nodeModules: any = {};
16+
1117
constructor(private $fs: IFileSystem,
1218
private $nodeModulesTree: INodeModulesTree,
1319
private $projectDataService: IProjectDataService,
1420
private $logger: ILogger) { }
1521

16-
public prepareNodeModules(absoluteOutputPath: string, projectDir: string): IFuture<void> {
22+
public prepareNodeModules(absoluteOutputPath: string, projectDir: string, lastModifiedTime?: any): IFuture<void> {
1723
return (() => {
18-
// TODO: figure out a better way for doing this
19-
this.$projectDataService.initialize(projectDir);
20-
let cachedNodeModulesPath = this.$projectDataService.getValue("node-modules-cache-path").wait();
21-
if (cachedNodeModulesPath && this.$fs.exists(cachedNodeModulesPath).wait()) {
22-
let diffTree = new TreeDiffer(cachedNodeModulesPath);
23-
let diffTreeResult = diffTree.diffTree(path.join(projectDir, absoluteOutputPath, "node_modules"));
24-
25-
if(diffTreeResult.changedDirectories.length > 0 || diffTreeResult.removedDirectories.length > 0) {
26-
this.rebuildNodeModulesTree(absoluteOutputPath, projectDir).wait();
27-
}
28-
} else {
29-
this.rebuildNodeModulesTree(absoluteOutputPath, projectDir).wait();
24+
let nodeModulesPath = path.join(projectDir, "node_modules");
25+
let future = new Future<any>();
26+
27+
if(lastModifiedTime) {
28+
let pipeline = gulp.src(path.join(projectDir, "node_modules/**"))
29+
.pipe(vinylFilterSince(lastModifiedTime))
30+
.pipe(through.obj( (chunk: any, enc: any, cb: any) => {
31+
let rootModuleName = chunk.path.split(nodeModulesPath)[1].split(path.sep)[1];
32+
if(rootModuleName) {
33+
let rootModuleFullPath = path.join(nodeModulesPath, rootModuleName);
34+
this.nodeModules[rootModuleFullPath] = rootModuleFullPath;
35+
}
36+
37+
cb(null);
38+
}))
39+
.pipe(gulp.dest(absoluteOutputPath));
40+
41+
pipeline.on('end', (err: any, data: any) => {
42+
if(err) {
43+
future.throw(err);
44+
} else {
45+
future.return(data);
46+
}
47+
});
48+
49+
future.wait();
50+
} else {
51+
let nodeModulesDirectories = this.$fs.readDirectory(nodeModulesPath).wait();
52+
_.each(nodeModulesDirectories, nodeModuleDirectoryName => {
53+
let nodeModuleFullPath = path.join(nodeModulesPath, nodeModuleDirectoryName);
54+
this.nodeModules[nodeModuleFullPath] = nodeModuleFullPath;
55+
})
3056
}
57+
58+
let destCopy = $injector.resolve(destCopyLib.DestCopy, {
59+
inputPath: projectDir,
60+
cachePath: "",
61+
outputRoot: absoluteOutputPath,
62+
projectDir: projectDir
63+
});
64+
65+
destCopy.rebuildChangedDirectories(_.keys(this.nodeModules));
66+
3167
}).future<void>()();
3268
}
3369

lib/tools/broccoli/node-modules-dest-copy.ts

+20-29
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,26 @@ import constants = require("./../../constants");
1414
* and tees a copy to the given path outside the tmp dir.
1515
*/
1616
export class DestCopy implements IBroccoliPlugin {
17-
constructor(private inputPath: string, private cachePath: string, private outputRoot: string, private projectDir: string) {}
18-
19-
public rebuild(treeDiff: IDiffResult): void {
20-
let dependencies = this.getDependencies();
21-
let devDependencies = this.getDevDependencies(this.projectDir);
17+
private dependencies: IDictionary<any> = null;
18+
private devDependencies: IDictionary<any> = null;
2219

23-
treeDiff.changedDirectories.forEach(changedDirectory => {
24-
let changedDirectoryAbsolutePath = path.join(this.inputPath, constants.NODE_MODULES_FOLDER_NAME, changedDirectory);
20+
constructor(private inputPath: string, private cachePath: string, private outputRoot: string, private projectDir: string) {
21+
this.dependencies = Object.create(null);
22+
this.devDependencies = this.getDevDependencies(projectDir);
23+
}
24+
25+
public rebuildChangedDirectories(changedDirectories: string[]): void {
26+
_.each(changedDirectories, changedDirectoryAbsolutePath => {
27+
//let changedDirectoryAbsolutePath = path.join(this.inputPath, constants.NODE_MODULES_FOLDER_NAME, changedDirectory);
2528
let packageJsonFiles = [path.join(changedDirectoryAbsolutePath, "package.json")];
2629
let nodeModulesFolderPath = path.join(changedDirectoryAbsolutePath, "node_modules");
2730
packageJsonFiles = packageJsonFiles.concat(this.enumeratePackageJsonFilesSync(nodeModulesFolderPath));
28-
31+
2932
_.each(packageJsonFiles, packageJsonFilePath => {
3033
let fileContent = require(packageJsonFilePath);
3134
let isPlugin = fileContent.nativescript;
3235

33-
if(!devDependencies[fileContent.name]) { // Don't flatten dev dependencies
36+
if(!this.devDependencies[fileContent.name]) { // Don't flatten dev dependencies
3437

3538
let currentDependency = {
3639
name: fileContent.name,
@@ -39,7 +42,7 @@ export class DestCopy implements IBroccoliPlugin {
3942
isPlugin: isPlugin
4043
};
4144

42-
let addedDependency = dependencies[currentDependency.name];
45+
let addedDependency = this.dependencies[currentDependency.name];
4346
if (addedDependency) {
4447
if (semver.gt(currentDependency.version, addedDependency.version)) {
4548
let currentDependencyMajorVersion = semver.major(currentDependency.version);
@@ -49,22 +52,26 @@ export class DestCopy implements IBroccoliPlugin {
4952
let logger = $injector.resolve("$logger");
5053
currentDependencyMajorVersion === addedDependencyMajorVersion ? logger.out(message) : logger.warn(message);
5154

52-
dependencies[currentDependency.name] = currentDependency;
55+
this.dependencies[currentDependency.name] = currentDependency;
5356
}
5457
} else {
55-
dependencies[currentDependency.name] = currentDependency;
58+
this.dependencies[currentDependency.name] = currentDependency;
5659
}
5760
}
5861
});
5962
});
6063

61-
_.each(dependencies, dependency => {
64+
_.each(this.dependencies, dependency => {
6265
shelljs.cp("-R", dependency.directory, this.outputRoot);
6366
shelljs.rm("-rf", path.join(this.outputRoot, dependency.name, "node_modules"));
6467
if(dependency.isPlugin) {
6568
shelljs.rm("-rf", path.join(this.outputRoot, dependency.name, "platforms"));
6669
}
6770
});
71+
}
72+
73+
public rebuild(treeDiff: IDiffResult): void {
74+
this.rebuildChangedDirectories(treeDiff.changedDirectories);
6875

6976
// Cache input tree
7077
let projectFilePath = path.join(this.projectDir, constants.PACKAGE_JSON_FILE_NAME);
@@ -73,22 +80,6 @@ export class DestCopy implements IBroccoliPlugin {
7380
fs.writeFileSync(projectFilePath, JSON.stringify(projectFileContent, null, "\t"), { encoding: "utf8" });
7481
}
7582

76-
private getDependencies(): IDictionary<any> {
77-
let result = Object.create(null);
78-
if(fs.existsSync(this.outputRoot)) {
79-
let dirs = fs.readdirSync(this.outputRoot);
80-
_.each(dirs, dir => {
81-
let filePath = path.join(dir, constants.PACKAGE_JSON_FILE_NAME);
82-
if(fs.existsSync(filePath)) {
83-
let fileContent = require(filePath);
84-
result[fileContent.name] = fileContent;
85-
}
86-
});
87-
}
88-
89-
return result;
90-
}
91-
9283
private getDevDependencies(projectDir: string): IDictionary<any> {
9384
let projectFilePath = path.join(projectDir, constants.PACKAGE_JSON_FILE_NAME);
9485
let projectFileContent = require(projectFilePath);

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@
6565
"shelljs": "0.3.0",
6666
"tabtab": "https://github.com/Icenium/node-tabtab/tarball/master",
6767
"temp": "0.8.1",
68+
"through": "2.3.7",
6869
"utf-8-validate": "https://github.com/telerik/utf-8-validate/tarball/master",
70+
"vinyl-filter-since": "2.0.0",
6971
"winreg": "0.0.12",
7072
"ws": "0.7.1",
7173
"xcode": "https://github.com/NativeScript/node-xcode/archive/NativeScript-0.9.tar.gz",

0 commit comments

Comments
 (0)