There have been lots of questions about this recently so I wanted to take the time to explain where we are.
The Problem
Many projects specify a Flow version in their .flowconfig file. This is useful because Flow upgrades usually introduce breaking changes, so projects can upgrade their Flow version at their own pace. Flow will refuse to start if its version does not match the version specified in the .flowconfig (Note: Nuclide will currently fail silently if this is the case -- I intend to have it pop up a message but I haven't gotten around to it yet).
This works fairly well within Facebook because we deploy a bunch of recent Flow binaries and call them through a wrapper script that first inspects the .flowconfig. So, you change the version in your .flowconfig and everything Just Works™️, even if you are working on projects that have different Flow versions. However, currently folks external to Facebook are expected to manage their own Flow versions. Without this wrapper script, there will typically be just one system-wide Flow version installed, so you are out of luck if you want to use different versions of Flow with different projects.
Potential Solutions
flow-bin
The Flow team publishes the flow-bin npm package every time they do a Flow release. You can use this to install Flow system-wide, or individual packages can add it as a devDependency to have their own version of Flow set. Then, you can just run the binary inside node_modules.
It would be trivial, from a technical perspective, to have Nuclide look inside node_modules for the copy of Flow installed by flow-bin.
Unfortunately, this is a glaring security vulnerability since Nuclide runs Flow all the time while you are browsing. So, just by downloading and browsing a malicious project, your machine will get completely owned. They could just have a repository with their code in node_modules/bin/flow or whatever the path is, and bam. Generally, people don't have the expectation that just browsing source code requires trust in the project they are looking at.
I'd be willing to implement a setting to enable this (with a scary description so people know the risk they are taking on), if there is demand, but that only works for people who know to ask for it. It would be better to fix this issue for everyone.
Distribute something like our internal wrapper script
When you install Flow, we could include a bunch of versions and have a central script that looks at the .flowconfig and decides which binary to actually run. Then, Flow externally would behave exactly like Flow internally and things would basically just work. No modifications to Nuclide would be necessary, and this also has the advantage (over the option below) that you can run Flow from outside of Nuclide, from the command line (useful for a variety of reasons, including debugging Nuclide/Flow issues). However it has the disadvantage that you still have to manually install Flow in addition to Nuclide
Bundle Flow with Nuclide
A few points about this:
- We probably don't want to actually bundle the binaries with a Nuclide install, so it would probably download them on-demand
- We also probably don't want to muck with your system when you install Nuclide, so this wouldn't make Flow available from the command line
Other than that, it's basically the same as above. Nuclide checks the .flowconfig for the right Flow version and then just runs it.
cc @zertosh @jeffmo @peterhal @koba04 @satya164
Twitter exchange that prompted this writeup: https://twitter.com/natmote/status/749009001329807361
There have been lots of questions about this recently so I wanted to take the time to explain where we are.
The Problem
Many projects specify a Flow version in their
.flowconfigfile. This is useful because Flow upgrades usually introduce breaking changes, so projects can upgrade their Flow version at their own pace. Flow will refuse to start if its version does not match the version specified in the.flowconfig(Note: Nuclide will currently fail silently if this is the case -- I intend to have it pop up a message but I haven't gotten around to it yet).This works fairly well within Facebook because we deploy a bunch of recent Flow binaries and call them through a wrapper script that first inspects the
.flowconfig. So, you change the version in your.flowconfigand everything Just Works™️, even if you are working on projects that have different Flow versions. However, currently folks external to Facebook are expected to manage their own Flow versions. Without this wrapper script, there will typically be just one system-wide Flow version installed, so you are out of luck if you want to use different versions of Flow with different projects.Potential Solutions
flow-binThe Flow team publishes the
flow-binnpm package every time they do a Flow release. You can use this to install Flow system-wide, or individual packages can add it as adevDependencyto have their own version of Flow set. Then, you can just run the binary insidenode_modules.It would be trivial, from a technical perspective, to have Nuclide look inside
node_modulesfor the copy of Flow installed byflow-bin.Unfortunately, this is a glaring security vulnerability since Nuclide runs Flow all the time while you are browsing. So, just by downloading and browsing a malicious project, your machine will get completely owned. They could just have a repository with their code in
node_modules/bin/flowor whatever the path is, and bam. Generally, people don't have the expectation that just browsing source code requires trust in the project they are looking at.I'd be willing to implement a setting to enable this (with a scary description so people know the risk they are taking on), if there is demand, but that only works for people who know to ask for it. It would be better to fix this issue for everyone.
Distribute something like our internal wrapper script
When you install Flow, we could include a bunch of versions and have a central script that looks at the
.flowconfigand decides which binary to actually run. Then, Flow externally would behave exactly like Flow internally and things would basically just work. No modifications to Nuclide would be necessary, and this also has the advantage (over the option below) that you can run Flow from outside of Nuclide, from the command line (useful for a variety of reasons, including debugging Nuclide/Flow issues). However it has the disadvantage that you still have to manually install Flow in addition to NuclideBundle Flow with Nuclide
A few points about this:
Other than that, it's basically the same as above. Nuclide checks the
.flowconfigfor the right Flow version and then just runs it.cc @zertosh @jeffmo @peterhal @koba04 @satya164
Twitter exchange that prompted this writeup: https://twitter.com/natmote/status/749009001329807361