ionic-team/ionic-cli

Deprecate State

imhoffd opened this issue · 16 comments

The state architecture (herein "state") in the CLI contains some of the oldest untouched code in the CLI. Its sole purpose is to provide easy management of Cordova platforms and plugins in Ionic apps through the ionic state command.

The majority of the state code can be found here: https://github.com/driftyco/ionic-app-lib/blob/master/lib/state.js

In this issue I will explain why state is now unnecessary (perhaps even harmful) and why it does not fit in with the goals of the Ionic CLI. I welcome all input.

State keeps a manifest of Cordova plugins and platforms in package.json. When a plugin is added via ionic plugin add, it inserts a record into the cordovaPlugins property. Similarly when a platform is added via ionic platform add, it inserts a record into the cordovaPlatforms property.

Just so everyone is up to speed as I go forward, ionic plugin/platform commands also call the cordova plugin/platform commands under the hood, which actually add/remove the platforms and plugins. These Cordova commands have always been around. What hasn't always been around in Cordova is the ability to save and restore platforms and plugins to your project. When you committed a Cordova project to git, you would ignore the platforms and plugins directories, unless you want a massive amount of ever-changing files and dependencies in your repo.

Enter March, 2015. Cordova 4.3.0 is released with just such a feature. There now is a way in Cordova itself to manage platforms and plugins. See Platforms and Plugins Version Management. With a simple --save option appended to the cordova platform/plugin commands, the platform and plugin versions are all saved in config.xml. Upon running cordova prepare, Cordova checks local installations, compares it with the manifest in config.xml, and updates the local project accordingly.

August, 2016. We still have state in the Ionic CLI and we still have active users of the ionic platform/plugin commands. This means we have two ways of managing dependencies in Ionic apps. Vanilla Cordova apps have no such confusion. Every Cordova plugin in the world has cordova plugin add foo somewhere in their docs or readmes. When to use ionic platform/plugin vs cordova platform/plugin? Does cordova prepare (run with cordova build or cordova run) overwrite the ionic state restore command I just ran? What version of this plugin am I truly using?

I remember hearing about a developer who lost an Ionic project on their local computer. Fortunately, it was pushed up to Github. But, when they pulled it down, they could not get it to work because the plugins had all updated APIs. They had installed plugins with cordova plugin add as well as ionic plugin add, so their manifest was incomplete and/or just wrong.

Having two ways to manage Cordova platforms and plugins also creates confusion in other areas.

Ionic Package, which builds Ionic apps in the cloud, receives constant questions about why a plugin is missing. (why is my app a white box?) It attempts to cater to both plugin management schemes. It parses plugins from cordovaPlugins, which is an array of locator strings, or sometimes objects, or sometimes a lovely mix of both. Then it goes through and manually runs cordova plugin add for each one. Plugins defined in config.xml are just automatically added during the cordova prepare step. I imagine teams that are working on Ionic apps have similar issues.

Action plan: Let Cordova manage Cordova stuff. Deprecate ionic state command in CLI 2.0 and remove it in 3.0, with an informational message about using Cordova to manage platforms and plugins. Do not deprecate ionic platform/plugin commands--some do more than just modify package.json. Remove the state code that is run during those commands, however.

Thoughts? @mlynch @jthoms1 @adamdbradley @ericb @tlancina

@gruppjo Would also love to hear your thoughts.

I'm all for removing state. What would we do with run/emulate, where the CLI is doing important stuff?

Hi @dwieeb, thanks for bringing this up and notifying me!

We've been having good experiences in Generator-M-Ionic with letting cordova manage platforms and plugins in the config.xml since the release of Cordova 4.3. I remember some initial issues but all has been very stable for months. We had a similar logic of managing cordova platforms and plugins before that but I'm really glad we ditched it because now it's just:

git clone
npm i && gulp --cordova 'prepare'

And everything's the way you expect it to be.

Just out of curiosity, which parts of the Ionic CLI simply wrap the Cordova CLI and where does the Ionic CLI add functionality? Using the Cordova CLI for everything Cordova related has worked very nicely for us. Additional benefit is that you can upgrade the Cordova CLI version independently from the Ionic CLI version.

there is one thing that always bothered me with the way cordova handles plugins, how is it possible that it is not possible to update plugins with the cordova CLI?
If I change the version in config.xml, the cordova CLI will not help me update the plugins, and I'll have to remove/add plugins everytime I update a plugin :(

@Freundschaft, not sure what this has to do with this discussion but I usually just make changes to the platform and plugins in the config.xml and then:

rm -rf platforms/ plugins/
cordova prepare # or: gulp --cordova "prepare" in a generator-m-ionic project

@gruppjo yes, its mostly a shortcoming of cordova here, but for me it was always kind of convenient, to make changes to package.json (e.g. update plugin to a new version) & run ionic state restore, but you're right of course, it doesnt belong to this discussion (by the way there is an issue at cordova to add a helper CLI command to update plugins https://issues.apache.org/jira/browse/CB-11752)

Please don’t remove ionic state just yet, as I think ionic state is more forgiving then Cordova Prepare. For example, Cordova Prepare requires image resources to already be physically available in the directory, and ionic state does not.

Details:

I love using “ionic state reset” in my continuous integration builds, because I prefer NOT to store platforms and plugins directly in my source repository, since they can always be restored during automated build. I also love using “ionic resources” to restore splash and icon image resources during automated builds, for the same exact reason. Admittedly, I wonder if either of these are a good practice or not.

When “ionic state reset” runs, it typically runs successfully regardless of accessibility to image resources. For example, my config.xml has: <icon src="resources/android/icon/drawable-xhdpi-icon.png”/>. If that file isn’t in my physical directory, ionic state reset doesn’t care, and successfully restores platforms and plugins.

When Cordova Prepare runs, it will error out when it finds a missing image resource. For example, my config.xml has: <icon src="resources/android/icon/drawable-xhdpi-icon.png”/>. When I run Cordova Prepare I get “Error: Source path does not exist: resources/android/icon/drawable-hdpi-icon.png.”

You might be asking, why not restore image resources before running Cordova Prepare then? My answer - because “ionic resources” requires platforms to already be restored, or it will give you an error about missing platforms. Hence, chicken-and-egg issue if I used Cordova Prepare - I cannot run ionic restore because platforms aren’t installed, and I cannot run Cordova Prepare because resources aren’t restored.

Like everyone, I think Cordova needs to use package.json to hold configuration for these platforms and plugins. I also think Cordova needs to make Cordova Prepare restore platforms and plugins, without confirming image resource availability in physical directory.

If you do remove ionic state reset, please consider giving developers ample time to adjust things, like automated builds.

What is the current state of this? Especially in relation to CLI v3?

sofqi commented

Using
Cordova CLI: 6.5.0 Ionic Framework Version: 3.1.1 Ionic CLI Version: 3.0.0-beta7

ionic state is no longer supported. Don't see how to replace it properly as ionic cordova prepare doesn't seem to work as well yet, but it might be something else.

What exactly are you missing @sofqi?

xavs commented

If I pull from a repository, and that pull has new plugins/update to plugins, with ionic state reset, I would get all the plugins listed in config.xml installed.
At the moment, I haven't found a way to do this. No errors are thrown so I just find out by plugin_not_installed when trying to use it at runtime.

ionic cordova prepare doesn't do that for you?

xavs commented

It didn't, I can achieve it by removing and adding platform, but prepare did not do anything

new to ionic3... just spent 2h looking for a way to do what i did in ionic2 with state restore... documentation on official website is awful

There are "improve documentation" links on every page of the documentation. Sure you edited the docs and submitted a PR after you found out how, right?

@frozenxis Can you link to the incorrect documentation?