Skip to content

Commit 97cf288

Browse files
Cherry pick fixes from release (#2529)
* Fix livesync when directories are modified In case you try adding/removing directories in your `app` dir, `chokidar` (the file system watcher that we are using now instead of `gaze`) raises `addDir`/`unlinkDir` events. However we do not have handles for these events, so we do not execute anything. After that, when we add a file in the newly created dir, `chokidar` sends `add` event, we handle it and try to process the file. This works fine for iOS and Android devices, but it does not work at all for iOS Simulator, as we have not transferred the new directory to `platforms` dir. Add required handles for `addDir` and `unlinkDir` methods. Also currently there's a problem when already existing directory is renamed. In this case its modified time (`mtime`) is not changed, so the projectChangesService disregards the change and doesn't transfer it to `platforms` dir. After that, in case you modify any file inside the renamed dir, you'll see ENOENT error. In order to fix this, check the time of last status change (`ctime`) of the directory/file. * LiveSync only existing files during `--watch` During `--watch`, when a change is detected, the project is prepared and after that we are trying to move the prepared file (from `platforms/<platform>/...` dir) to the device. However some plugins modify the content of the `platforms` directory on afterPrepare. For example `nativescript-dev-sass` allows you to use `.scss` files, on `beforePrepare` they are "transpiled" to `.css` files. After that, on `afterPrepare` the plugin itself removes the file from `platforms/<platform>/...` dir. CLI detects the change in `.scss` file, prepares the project (which moves the `.scss` file to `platforms` dir) and after that tries to move it from `platforms` to the device. During the last step, the `.scss` file is already removed from `platforms` directory, so our code fails. Meanwhile, the `beforePrepare` hook of the plugin has created/modified the `.css` file inside `app` dir. This will trigger new iteration, where the file will be sent to device. In order to fix the error when the `.scss` file is modified, we'll execute livesync only if the modified files exist in `platforms` dir. * Pass current stdio to npm install process Whenever CLI spawns `npm install <smth>`, we do not set stdin and stdout of the spawned process. This way in case any of the npm scripts executed during install requires input from user, it cannot be handled in any way. So pass the current stdin and stdout to the spawned npm process. This way in case a postinstall script is executed and it requires input from user, the users will be able to enter required information in the same place where `tns` command has been executed (same terminal). This fixes postinstall execution of `nativescript-plugin-firebase`. * Add missing dependency
1 parent 3596891 commit 97cf288

File tree

5 files changed

+30
-7
lines changed

5 files changed

+30
-7
lines changed

lib/node-package-manager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export class NodePackageManager implements INodePackageManager {
3838
}
3939
}
4040
try {
41-
let spawnResult: ISpawnResult = await this.$childProcess.spawnFromEvent(this.getNpmExecutableName(), params, "close", { cwd: pwd });
41+
let spawnResult: ISpawnResult = await this.$childProcess.spawnFromEvent(this.getNpmExecutableName(), params, "close", { cwd: pwd, stdio: "inherit" });
4242
this.$logger.out(spawnResult.stdout);
4343
} catch (err) {
4444
if (err.message && err.message.indexOf("EPEERINVALID") !== -1) {

lib/services/livesync/livesync-service.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ class LiveSyncService implements ILiveSyncService {
140140
try {
141141
filePath = path.join(syncWorkingDirectory, filePath);
142142
for (let i = 0; i < onChangedActions.length; i++) {
143+
that.$logger.trace(`Event '${event}' triggered for path: '${filePath}'`);
143144
await onChangedActions[i](event, filePath, that.$dispatcher);
144145
}
145146
} catch (err) {

lib/services/livesync/platform-livesync-service.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ export abstract class PlatformLiveSyncServiceBase implements IPlatformLiveSyncSe
2222
private $projectFilesProvider: IProjectFilesProvider,
2323
private $platformService: IPlatformService,
2424
private $projectChangesService: IProjectChangesService,
25-
private $liveSyncProvider: ILiveSyncProvider) {
25+
private $liveSyncProvider: ILiveSyncProvider,
26+
private $fs: IFileSystem) {
2627
this.liveSyncData = _liveSyncData;
2728
}
2829

@@ -58,9 +59,9 @@ export abstract class PlatformLiveSyncServiceBase implements IPlatformLiveSyncSe
5859
return;
5960
}
6061

61-
if (event === "add" || event === "change") {
62+
if (event === "add" || event === "addDir" || event === "change") {
6263
this.batchSync(filePath, dispatcher, afterFileSyncAction);
63-
} else if (event === "unlink") {
64+
} else if (event === "unlink" || event === "unlinkDir") {
6465
await this.syncRemovedFile(filePath, afterFileSyncAction);
6566
}
6667
}
@@ -172,8 +173,21 @@ export abstract class PlatformLiveSyncServiceBase implements IPlatformLiveSyncSe
172173
isFullSync = true;
173174
} else {
174175
deviceAppData = this.$deviceAppDataFactory.create(this.liveSyncData.appIdentifier, this.$mobileHelper.normalizePlatformName(this.liveSyncData.platform), device);
175-
let mappedFiles = filesToSync.map((file: string) => this.$projectFilesProvider.mapFilePath(file, device.deviceInfo.platform));
176+
const mappedFiles = filesToSync.map((file: string) => this.$projectFilesProvider.mapFilePath(file, device.deviceInfo.platform));
177+
178+
// Some plugins modify platforms dir on afterPrepare (check nativescript-dev-sass) - we want to sync only existing file.
179+
const existingFiles = mappedFiles.filter(m => this.$fs.exists(m));
180+
181+
this.$logger.trace("Will execute livesync for files: ", existingFiles);
182+
183+
const skippedFiles = _.difference(mappedFiles, existingFiles);
184+
185+
if (skippedFiles.length) {
186+
this.$logger.trace("The following files will not be synced as they do not exist:", skippedFiles);
187+
}
188+
176189
localToDevicePaths = await this.$projectFilesManager.createLocalToDevicePaths(deviceAppData, this.liveSyncData.projectFilesPath, mappedFiles, this.liveSyncData.excludedProjectDirsAndFiles);
190+
177191
await fileSyncAction(deviceAppData, localToDevicePaths);
178192
}
179193

lib/services/platform-service.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,9 @@ export class PlatformService implements IPlatformService {
211211

212212
await this.ensurePlatformInstalled(platform);
213213
let changesInfo = this.$projectChangesService.checkForChanges(platform);
214+
215+
this.$logger.trace("Changes info in prepare platform:", changesInfo);
216+
214217
if (changesInfo.hasChanges) {
215218
await this.preparePlatformCore(platform, changesInfo);
216219
this.$projectChangesService.savePrepareInfo(platform);

lib/services/project-changes-service.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,12 +176,16 @@ export class ProjectChangesService implements IProjectChangesService {
176176
if (filePath === skipDir) {
177177
continue;
178178
}
179+
179180
let fileStats = this.$fs.getFsStats(filePath);
180-
let changed = fileStats.mtime.getTime() > this._outputProjectMtime;
181+
182+
let changed = fileStats.mtime.getTime() > this._outputProjectMtime || fileStats.ctime.getTime() > this._outputProjectMtime;
183+
181184
if (!changed) {
182185
let lFileStats = this.$fs.getLsStats(filePath);
183-
changed = lFileStats.mtime.getTime() > this._outputProjectMtime;
186+
changed = lFileStats.mtime.getTime() > this._outputProjectMtime || lFileStats.ctime.getTime() > this._outputProjectMtime;
184187
}
188+
185189
if (changed) {
186190
if (processFunc) {
187191
this._newFiles++;
@@ -193,6 +197,7 @@ export class ProjectChangesService implements IProjectChangesService {
193197
return true;
194198
}
195199
}
200+
196201
if (fileStats.isDirectory()) {
197202
if (this.containsNewerFiles(filePath, skipDir, processFunc)) {
198203
return true;

0 commit comments

Comments
 (0)