NativeScript / nativescript-cli

Command-line interface for building NativeScript apps
https://www.npmjs.com/package/nativescript
Apache License 2.0
1.04k stars 195 forks source link

Feature request: launch emulators from tns run #3009

Open tjvantoll opened 7 years ago

tjvantoll commented 7 years ago

My typical NativeScript workflow is to launch emulators for development using either tns run ios or tns run android. Since version 3.1.3, the {N} CLI now supports running tns run to deploy to multiple devices, which is awesome... but there’s no way for that command to launch emulators like tns run ios and tns run android do.

I need to manually start iOS simulators from Xcode, and Android AVDs from Android Studio, and then execute tns run to get the workflow I’m looking for. This isn’t horrible, but I’m wondering if we can make this common workflow a little less tedious.

I don’t think tns run should open emulators by default, but maybe we could introduce some new flags.

tns run --launch-ios-emulator --launch-android-emulator

Thoughts on this? Other ideas for how tns run could launch emulators?

mikebranstein commented 7 years ago

My workflow is like yours, @tjvantoll. I don't want the CLI to auto-open multiple emulators, and just because I have AVD and Geny installed, I don't want to launch them both. I like the opt-in model proposed.

ejsuncy commented 7 years ago

FWIW, before the tns run feature for launching both ios and android was added, I intuitively attempted the command tns run ios android --emulator, hoping it would launch both emulators

jlooper commented 7 years ago

I have the same workflow, normally starting with iOS, then moving to Android. But if I could simply have tns run launch my iOS emulator and my AVD emulator when none were open, that would be very sweet. For me, opt-in = typing tns run ios and then later on tns run android. If one or the other is already open, then maybe tns run would simply launch the opened emulator. I'm a bit leery of introducing flags b/c I'm absolutely sure I won't remember them :)

rosen-vladimirov commented 7 years ago

Hey @jlooper , Just to clear the idea and see if I understand you correctly, can you check the questions below:

  1. What if you have a connected iOS device and Android device - in this case the tns run command should not start emulators/simulators, right?
  2. Also in case you have only Android device/emulator, you would like tns run to start iOS Simulator, if I understand you correctly?
  3. And in case there's no devices/emulators/simulators currently running, you would like tns run to start Android emulator and iOS Simulator?
jlooper commented 7 years ago

@rosen-vladimirov

Interesting use cases. I hadn't considered this question in light of using connected devices. I agree with 1, 2, and 3. Two devices = 0 emulators 1 device = device + 1 opposite emulator 0 devices = 2 emulators

Is that a solid workflow in your opinion, @tjvantoll?

rosen-vladimirov commented 7 years ago

Btw the tns run command will work with all connected devices and running emulators/simulators. For example, in case you have one Android device, two Android emulators, one iOS device and one iOS Simulator, tns run will work with all of them and livesync on all of them. We've implemented a lot of optimizations to reduce the number of builds in such cases (there will be three builds - one for Android devices and emulators, one for iOS device and one for iOS simulator). So practically, tns run command can be used to test your app on different devices, API Levels, etc. simultaneously. Also, as far as I know, Xcode 9 will allow starting multiple iOS Simulators at the same time and our idea is tns run to work with all of them simultaneously. My personal idea for this feature was to test applications on emulators with Android SDK 21, 22, 23... and iOS versions 9, 10... with minimum efforts - just take care of your code and CLI will handle all required steps to build and deploy it on all of the devices.

tjvantoll commented 7 years ago

So I think we have two different proposed options.

1) tns run launches an emulator automatically if there are zero connected devices/emulators for each platform. This is the workflow @jlooper proposed.

2) We add two new flags, --launch-ios-emulator and --launch-android-emulator, and tns run only launches emulators when the user provides those flags.

I’m cool with either—both get me the workflow I’m looking for. Votes? More ideas?

@rosen-vladimirov I’m curious if either of these options will be easier to implement and maintain.

ejsuncy commented 7 years ago

I vote for 1.

In the case of 2, omitting the flags with no connected devices would cause tns run to do nothing?

petekanev commented 7 years ago

@ejsuncy I would not like it if tns run started emulators for me. It could be that I've forgot to start up my own Geny emulator, or have forgotten to connect back a device, I would have to rush to spam the X button, trying to kill the emulators that would otherwise start up.

A tns run with no connected devices should throw an error that no devices are connected, and suggest that some are started, or that the user explicitly executes tns run android/ios respectively.

ejsuncy commented 7 years ago

@Pip3r4o You're right, that would be annoying. I like the idea of tns run throwing an error when no devices are attached and giving suggestion/reminder of what the flags are (those are really long flags) to launch the emulators

tjvantoll commented 7 years ago

In the case of 2, omitting the flags with no connected devices would cause tns run to do nothing?

Correct, and that’s the behavior of tns run today with the latest 3.1.3 release.

those are really long flags

Yes they are. Suggestions welcome 😄

rosen-vladimirov commented 7 years ago

@tjvantoll , the implementation of any of the solutions will require almost the same effort. The problem with -- options is that they are often forgotten and historically we've introduced a lot of options (some of them can still be found in CLI's code) and later we've found noone is using them. However, in this case I belive it will be safe to introduce a new -- option. But what do you think to introduce only one flag that will start all required emulators/simulators. For example:

  1. In case you have Android device and you run tns run --launch-emulator, we'll start iOS Simulator.
  2. In case you have iOS device and you run tns run --launch-emulator we'll start Android emulator and we'll work with the device and the emulator.
  3. In case you do not have any running emulators/simulators and no devices are attached, tns run --launch-emulator will start iOS Simulator and Android emulator and will work with them

This can be extended by combining it with --emulator flag that CLI currently has. For example tns run --launch-emulator --emulator will start both iOS Simulator and Android device in cases 1. and 2. above as there's no running emulators/simulators for both platforms.

And of course, as long -- options are easy to be misspelled on the terminal, we can introduce a shorthand for --launch-emulator , for example -l, or -r. What do you think about this?

I'm still not sure what should be the behavior in case tns run is executed and there are no running emulators and attached devices. As the user had written tns run maybe a behavior similar to tns run ios and tns run android will be expected, i.e. starting the required emulators/simulators. In cases where I already have device attached or simulator running, I would use tns run as a shorthand (I have only one device, why should I specify the platform in the command) and I would not expect the command to start a new simulator/emulator.

tjvantoll commented 7 years ago

The problem with -- options is that they are often forgotten and historically we've introduced a lot of options (some of them can still be found in CLI's code) and later we've found noone is using them.

For sure. And it’s not just in the code. I’m not looking forward to explaining this workflow in the Getting Started Guides if we end up with something too crazy 😛

Back to the point. I think the situations you spell out in 1–3 are exactly how I’d expect this new option to work. Thanks for spelling that out in detail @rosen-vladimirov.

I keep trying to think of better syntax for this, because tns run --launch-emulator still feels kind of meh... but every other idea I get is worse—tns launch ios, tns launch-emulator ios, tns run both, and so on. tns run --launch might be ok, but I personally prefer the specificity of --launch-emulator.

API design is hard.

sebawita commented 7 years ago

I don't think tns run should launch any emulator unless instructed to. If there are no running emulators or connected devices, then the CLI should return an error message with a suggested command required to start an emulator. I like the idea of having --launch-emulator flags and a short hand for them. I am just thinking whether --emulator(s) wouldn't be enough. As we would only launch when needed, if an emulator is already running then we would like to run the app in the emulator.