Skip to content

Fix livesync/run issue #2508

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 9, 2017
Merged

Conversation

rosen-vladimirov
Copy link
Contributor

@rosen-vladimirov rosen-vladimirov commented Feb 8, 2017

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.

Fixes #2476

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.
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.
@rosen-vladimirov
Copy link
Contributor Author

run ci

@dtopuzov
Copy link
Contributor

dtopuzov commented Feb 9, 2017

It looks with those changes we will not handle cases when user add new files, which is important case for getting started. All tutorials start with: tns run android, modify this file, then add new file, write code, require new file in the old file and so on.

@rosen-vladimirov
Copy link
Contributor Author

rosen-vladimirov commented Feb 9, 2017

@dtopuzov when user adds new file, it will be successfully synced to device. No changes in this behavior.
This PR addresses two problems:

  1. We skip prepare when a new directory is added to app dir, which leads to ENOENT error (easily reproducible with iOS Simulator).
  2. Some plugins modify the content of the files in the platforms dir and if I have to be precise, nativescript-dev-sass plugin removes some files from platforms directory. Meanwhile CLI tries to transfer the removed files from platforms dir to device. But they do not exist in platforms dir anymore (they still exist in app dir). Due to incorrect behavior in previous versions of NS CLI (2.4.x and earlier), the error was not visible to the end users. However we've fixed the incorrect behavior and now the error is shown. This PR addresses this by checking the files in platforms dir before trying to send them to device.

What happens before this PR when nativescript-dev-sass plugin is used:

  1. tns run android - project is prepared and started on device. File system watcher is started.
  2. modify .scss file in app dir
  3. CLI's watcher detects this change and starts livesync logic. The logic itself executes the following steps:
    3.1) execute beforePrepare hook - at this point nativescript-dev-sass plugin will convert .scss file to .css in app dir
    3.2) execute prepare logic from CLI - this will move all changed files (.scss in this case) to platforms dir
    3.3) execute afterPrepare hook - at this point nativescript-dev-sass plugin deletes the .scss file from platforms dir.
    3.4) Transfer modified file (.scss) from platforms dir to device. Before this PR, CLI fails at this point and shows warning to the user
    So I've modified step 3.4 to check if the file (.scss in the example described here), really exists inside platforms dir.

Please note that step 3.1 will trigger additional iteration of the whole cycle, as the .css file is modified.

@rosen-vladimirov rosen-vladimirov merged commit 2746bff into release Feb 9, 2017
@rosen-vladimirov rosen-vladimirov deleted the vladimirov/fix-livesync-dirs branch February 9, 2017 21:03
@irman
Copy link

irman commented Feb 16, 2017

How can I get this fix? I see it's on release branch but how do I update it with npm? There's no 2.5.1 listed on the npm repo too.

image

@Plamen5kov
Copy link
Contributor

@irman, we haven't published it yet, but it should be published by the end of the week.

@irman
Copy link

irman commented Feb 17, 2017

@Plamen5kov great to hear that. Can't wait. 😄

Thanks!

@vincentpalita
Copy link

@Plamen5kov

is the package already available on npm? It seems to but I still having the same issue with nativescript-dev-sass.

Thanks for your help

@Plamen5kov
Copy link
Contributor

@vincentpalita yes, 2.5.1 cli is published, and if you do a tns --version you should see printed out version 2.5.1. Please check you have the latest CLI installed, and if the problem still persists, we'll continue investigating the problem.

@vincentpalita
Copy link

@Plamen5kov,

Ok I had to remove manually the version then install it back and it is now ... working :)

That's great!
Thank you so much

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants