-
Notifications
You must be signed in to change notification settings - Fork 28
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
Unified cordova fetching and create cordova-fetch module #33
Conversation
Will this work with NPM 3+ and previous versions? |
It should work with npm 3 and npm 2. It would use whatever the user has installed. |
There is an advantage to locking down version of npm as we currently do. As on different machines different versions of npm might not be compatible even for the same version of cordova. We might need to warn if that happens instead of it failing with some random error on certain machines. |
Overall, this looks like a good refactoring to pursue - however, we might need a lot of tests to ensure we do no have any regressions. :) |
Thanks @nikhilkh! Definitely going to need to test this well to make sure we don't have regressions. It will be important to test this with at least all major versions of npm (1, 2, 3). I do see the advantage of locking down the npm version (no surprises with system versions). But I don't foresee any issues with using the system npm. We would just be using Running It is actually the recommended to shell out to system npm over using Sidenote: We also have to take into account some of the npm utility methods we created. [1]. Will have to see if it makes sense for this to live in cordova-fetch. This obviously won't be ready for cordova 6 release. |
@stevengill this looks good same thing we talked on Slack. Remind me again why do we need to run 'npm cache add' ? why no just rely on 'npm install' and let npm decide if it will use the cache or not, or check if its in the cache or not and son on... |
To be honest, I don't have a good reason to stick to My short term plan was to continue using Going the I think it makes sense to use |
@nikhilkh what are your thoughts on the above? |
@stevengill OK make sense this is just a baby step in the final goal of using package.json and project/node_modules Let's skip using putting our hand into ~/.npm or using npm cache add. Sounds good to use ~/.cordova but I would use ~/.cordova/lib/node_modules instead This allows if the user wants to pre-load the library it should only need to run npm install in the directory ~/.cordova/lib/ (copy the node_modules from another place) This allows to build servers for ci/builds that don't have access to npm or network, he can load the library with [email protected], [email protected], [email protected], , and even private plugins. Then using cordova 6 and adding specific versions of platforms and plugins cordova-cli will just grab them from the library (~/.cordova/lib/node_modules) if present then avoiding calling npm or connection to network. thoughts? |
These have been discussed in JIRA and Slack, but just making a note here to capture them:
|
Thanks @dpogue! I have a board to track all of these issues and more. https://issues.apache.org/jira/secure/RapidBoard.jspa?rapidView=109&view=detail |
So I need to revise this proposal after running into some issues. Before I get to the issues, I made some modifications of how cordova-fetch proposal I was working on. Mainly, both gitURLs and PackageIDs get This idea of Local paths never need to get fetched so they never make it to cordova-fetch. Now, my two separate issues here.
Potential solutions: For 2) I'm thinking of using a diff of the dependency tree when installing a So this proposal will have to be done in conjunction with It is more work than I was hoping to do at this time but I think it is the best long term solution. Definitely cordova@7 Thoughts? |
As expected, I'm totally 💯 👍 on the node_modules idea, and saving to package.json. |
I would recommend approaching this work incrementally as you had originally planned. Ideally, we can keep all the current code working as is and have an opt-in mechanism for the new path using npm-fetch and get feedback by releasing with it every release of 6.x. We know this will have a significant impact on downstream tools, distributions, and build servers. Moving from storing plugins/platforms from config.xml to package.json exposes this to the users as well - and would be disruptive for upgrade scenarios. It's hard to foresee how this play out and using an incremental approach with every release would be great. Perhaps this is great topic for a google hangout discussion. We haven't had one in a bit. :) |
Opened a PR with fetch. So far, I've added only integrated it with platform add/rm/update and behind the --fetch flag. cordova-lib: apache/cordova-lib#407, cordova-cli: apache/cordova-cli#239 A few things to note:
Plugin and template integration to come shortly. |
Also, still need to integrate apache/cordova-lib#382 so we can get logs/verbose events passed into cordova-cli. |
Another point, every module needs a package.json now. So plugins without package.json need to add one to work with fetch |
I updated the proposal yesterday. Let me know your thoughts @nikhilkh @purplecabbage @dpogue |
* Stop using `.cordova/npm_cache/`. Modules instead get fetched to root `node_modules` directory in your applications | ||
* Add new `--fetch` flag to `cordova` and `plugman` to use `cordova-fetch` over existing fetching methods | ||
* Plugin/platform removal should run `npm uninstall` on your cordova projects to remove the module from the apps `node_modules` directory. | ||
* if a `package.json` exists, adding `--save` will also add the dependency to `package.json` (as well as to `config.xml`). This won't be used until a future update is made to move save functionality from `config.xml` to `package.json`. Just adding it now for future proofing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm assuming if --fetch is not specified we should not save it to package.json.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup
I'm all in favour of storing platform and plugins in package.json, but I don't think all of config.xml should be moved there. The rest of config.xml (the actual application config stuff) should aim to move to the W3C Web App Manifest format. |
|
||
### New Requirements | ||
|
||
* Have to remove support for installing plugins/platforms from git subdirectoires. https://cordova.apache.org/docs/en/5.0.0/guide/cli/#advanced-plugin-options. I recommend we add deprecation notices for this ASAP. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I like that we do not have to support git cloning in our own code. There are some advantages that this code provides us - and one of them is to be able to control some of these features. There is also some desire to support submodules:
apache/cordova-lib#424
#38
Letting npm do it's thing - implies we might have to wait for npm to support these features.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the goal is to move plugins and platforms to package.json under dependencies, then we have to align with what npm supports. I think this should be the goal.
If we keep our own git cloning around (that supports subdirectories and submodules), we would be forced to continue to save our dependencies in config.xml or some other non standard attribute in package.json. Saving git references npm doesn't support under package.json dependencies attribute is asking for trouble.
I think our code would be simpler to maintain, and app dependency management would easier to understand for cordova app developers if we adopt the standard npm way of doing things. We can then maybe focus on contributing support for subdirectories/submodules to npm itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we try to support most common use cases, and most success for users.
Supporting subdirectories and submodules, its an advance/edge case that can be manage by the user to do the git cloning downloading and use the local folder , npm also support specifying dependecies using file:../foo/bar
meaning you can npm install /dir/mygitproject/somesubdir/withnpmpackage.json or cordova plugin add /dir/mygitproject/somesubdir/ --fetch
@dpogue We can discuss that more when the time comes. I'm also not entirely sure it makes sense to move everything over from config.xml to package.json but once the time comes, we can make a list and see what makes sense. At the very least, engine tags & platform/plugin save should be moved over to use package.json. |
I agree time will come to create a table what stays in config.xml and what goes into package.json. At least in my mind I see it as a separation of concerns where: |
To be honest I would favor letting npm fetch the dependencies or subprojects as well. I found git submodules to be a pain to deal with. For example, building SQLCipher for Android: https://github.com/sqlcipher/android-database-sqlcipher |
Could we add a "git" flag to fetch using git, which would allow subdirectories, and use npm otherwise? |
@brodybits the issue is where to save the dependency if we use the --git flag. My ultimate goal here is to save dependencies in package.json. You can't/shouldn't add a git reference that npm can't handle in the dependency tag in |
github is supported via an id of 'gitusername/gitreponame' Is there a reason to support it more deeply than that? @purplecabbage On Fri, Apr 22, 2016 at 11:34 AM, Steve Gill [email protected]
|
Github will be supported as npm supports it. That is what I am going for. What we won't be able to support are subdirectories (one repo with many plugins) and git submodules as npm doesn't support them. |
I agree with Steve, we should draw a line we can't support everything.
|
|
||
### Quirks | ||
|
||
* Currently, I am using a diff of `npm ls` to determine which module was just installed. This is because the user can pass in a git url as a target to `cordova-fetch`. If the git url repo-name is different than the `package.name`, only way to get what module was just installed is by doing a diff before and after the installation. The diffing technique can fail if the user is adding a module that has already been npm installed. Luckily cordova doesn't allow adding platform/plugin which has already been added. cordova platform/plugin rm will also remove the module from the applications `node_modules` directory. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's the scenario:
I am setting up a new machine and just downloaded a cordova project from the source control. What am I supposed to do in the "fetch" world?
"npm install" or "cordova prepare". If I do npm install - then how does the plugins/ directory get hydrated? If I do cordova prepare - do I have to do npm install later as well? Sounds like the ordering of these operations is important. Am I missing something here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really don't like that "cordova prepare" install dependencies
I think for for CLI 7.x we stop this, and have the user "npm install" or come up with a "cordova install" that parse config.xml and maybe also "npm install"
"cordova prepare" should only be concern with small task it got too broad of a kitchen sync
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Who creates the platforms/ & plugins/ directory? Someone has to...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cordova platform add and cordova plugin add takes care of creating those directories.
In addition like I said running "cordova install" it will run "platform add" and "plugin install" to move content/copy/install content from node_modules/ to platforms/plugins/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cordova prepare currently restores based on what is saved in config.xml and what is installed. I would think it would continue to do the restore step but use package.json instead of config.xml.
So if a user runs npm install
, then cordova prepare
, it would see that those plugins & platforms aren't "installed" according to cordova, so it would go through the motions of fetching (Which is already done since the user ran npm install
), then copying to platforms/plugins.
If a user doesn't run npm install
, cordova prepare would detect that those plugins/platforms aren't "installed" and move forward with fetching.
So cordova can support both usecases 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, Steve! It will be great to add the details of how that will work to this proposal. However, diffing does not work in this case - correct? Are you thinking there would be custom json properties in package.json that identify plugins and platforms in addition to them being referenced in "dependencies"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I remember problems reported by community members maybe @dpogue that installing things with "cordova prepare" was too much magic and not handling well some use cases, and a "cordova install" would make more sense, or something explicit because right now is preparing and installing if missing, so something like "cordova prepare --install" it will prepare and install just in case.
Maybe @dpogue can provide more details about having a "cordova install"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only problem I recall with cordova prepare
is that it makes testing and building a single platform difficult in a multi-platform project.
If my config.xml has both iOS and Android platforms, and I run cordova platform add ios && cordova build
, it will trigger a prepare that will also install the Android platform.
I think the best option would be for cordova prepare
to copy the platforms and plugins from node_modules as needed, but rely on npm install
for installation and fetching.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to @nikhilkh's concern about detecting already fetched/installed plugins. I'd suggest to add a property to every package.json
to indicate the type of package: plugin or platform. Also having such we could easily enumerate installed plugins just by checking every module's package.json
(and probably eliminate the need for copying these plugins from node_modules
to plugins
directory)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a bad idea @vladimir-kotikov. Worth revisiting once first implementation is complete.
If we support installing plugins using |
* Start using system installed `npm` instead of packaging our own `npm` in `cordoba-lib`. We already check for `git` being installed, we should do the same for `npm`. We would use `superspawn` to shell out to the system `npm`. | ||
* Stop using `.cordova/npm_cache/`. Modules instead get fetched to root `node_modules` directory in your applications | ||
* Add new `--fetch` flag to `cordova` and `plugman` to use `cordova-fetch` over existing fetching methods | ||
* Plugin/platform removal should run `npm uninstall` on your cordova projects to remove the module from the apps `node_modules` directory. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another idea (crazy enough, but it let us to transfer even more responsibilities to npm) is that we might just run npm uninstall
as a main action and do the rest of the things to actually remove plugin/platform via NPM hooks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've thought about this too. It is too big of a change IMO. Every third party plugin would need to add that hook.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hook is not necessarily needs to be shipped with dependency package - we can put our own hook into node_modules/.hooks/uninstall
and it'll be called for every package being removed.
Actually, at the second thought it might be not a good idea, as it would spread uninstallation logic onto two separate places and would make maintaining it too complex ;(
It will be great to highlight what are the key merits of this new approach to an end user - my concern with using npm's persistence mechanism - package.json and npm commands like "npm install" - we lose control over the workflow - where & what files get downloaded, how constraints to other components are matched etc. - as we try to address some of those limitations, we might create more complexity and dependencies on how npm currently behaves ( Having our own commands - cordova plugin add, and our own persistence format - config.xml affords the flexibility and control of doing what's right for cordova customers which are dealing with native SDKs of multiple platforms. Our plugins and platforms not a "typical" npm module (they ship java, objective-c code - not only js) and I wonder if we should even aspire to be one. Config.xml is not going away anytime soon - there is a lot that needs to be encoded there e.g. the current PR to manipulate manifests. |
I also don't like losing "control over the workflow". Extra rant: The one thing I don't like is that |
I think this discussion in here has gone out of scope for this proposal. Lets save npm install vs cordova platform/plugin add/rm for a later time. Same goes for package.json vs config.xml. |
I updated the proposal. --template now supports --fetch. It fetches it to I believe this proposal can be merged now. |
LGTM. Lets merge this. |
LGTM |
Take a look at the proposal and let me know what you think.