[Commandbox] module dependency uninstallation

So I have been trying to get comfortable setting up my new app using CB4 and commandbox. I noticed that if I uninstall a specific module that has a dependency, that the dependencies for that module are all uninstalled as well, regardless if I had them installed already. For example if I install testbox for my testing purposes then install Relax and then decide to uninstall Relax it then uninstalls Testbox which I already had installed and wanted for my testing purposes. Is this a configuration of my box.json file that I am missing or just a bug? Thanks,

That could be problematic for any other module that depends on that dependency, I would raise a ticket for that.

That behavior might not be what you wanted in this case, but it is expected-- meaning we wrote it that way. I am open to improving it, but the trick is how would you recommend we go about determining what dependencies might also be required by another dependency?

In NPM/Node, hierarchical modules are a first class citizen of the platform so dependencies are installed in a subfolder under the module that requested them. So in your case, TestBox would have already existed at the top level to satisfy the dependency, but when uninstalling relax, we would have only removed the dependencies nested under it. However, CFML does not have the same concept of nested modules (or even modules at all) so most libraries get dumped in the web root, or in the root of the modules folder. This makes it quite a lot more difficult to keep track of who was using what.

Now I’ll note that ColdBox specifically will be able to support nested modules in the near future which will help, but not all CF packages will be modules and not every developer will be using ColdBox either which makes it even harder to find a solution that will work for everyone. In general, CF’s lack of first-class modularity combined with CF developers’ resistance to conventions/frameworks has added a lot of trouble to the package manager part of CommandBox.

Also, we have a dedicated CommandBox Google Group here for further discussions:

https://groups.google.com/a/ortussolutions.com/forum/#!forum/commandbox

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Bard,

Yep, that’s going to be problematic. Maybe a config setting for now, whether they get removed or not and by default have it off.

I was thinking about this some more over the weekend. My first thought was to look in the root box.json and see if the package was listed there as that would mean it was explicitly installed by the user. Nested dependencies aren’t stored in the main app’s box.json since they’re listed as a dependency of the package requiring them.

For example, look at the attached image. The code for this example is here:
https://github.com/bdw429s/ColdBox-Dependency-Sample-App You can run this app but cloning it and running “install” from the web root in CommandBox.

The app’s box.json only has coldbox, testbox, and weather listed as dependencies:

“dependencies”:{
“coldbox-be”:“4.0.0”,
“weather-lookup-by-ip”:“1.0.0”
},
“devDependencies”:{
“testbox”:“2.0.0”
},

And if you look at the weather module, it’s box.json has the geolocation module listed as a dependency.
https://github.com/bdw429s/Weather-Lookup-By-IP

“dependencies” : {
“geolocation-lookup-by-ip” : “2.0.0”
}

Since geolocation isn’t in the main app’s list of dependencies, I can conclude that it has only been installed as a nested dependency and not explicitly by a user.
However, this doesn’t account for the possibility that ANOTHER unrelated module has ALSO asked for geolocation to be installed as well. That is another scenario in which I wouldn’t want to remove the nested dependency since it is potentially still need by other package.

So, I’ve come to the conclusion that the only real way to see what packages aren’t in use is to recursively scan through every package that’s installed and build up a list of all the package currently referenced by another installed package. Kind of like a combination of “npm list” and “npm prune”. So, perhaps the best recourse is to implement our own “list” and “prune” commands and then make it an option to run “prune” after uninstalling a package.

Thoughts?

Thanks!

~Brad