The package system will be an improvement and an eventual replacement to the current way of importing/exporting xmls. It will be a system that manages Mudlet objects - aliases, triggers, timers, scripts, keybindings, buttons. It will not mess with the Lua part of scripts or enforce namespaces in Lua scripts. Instead, a package will define the items it's interested in via a Lua table (a graphical interface will be provided to manage this in future updates) and Mudlet will provide the interface to install a package, upgrade (remove+import objects), downgrade (install a package of an earlier version), uninstall a package (remove objects) and completely uninstall a package (remove objects + raise event handlers for a script to delete its persistent on-disk data). In essence, a package will consist of metadata and current Mudlet settings.
Packages will have the ".mp" (mudlet package) extension (MIME content type: application/mudletpackage). I suggest that they be zipped by default to save space, or at least support zipping.
Packages will allow external resources to be bundled with them, in which case .mp will be a zipped up folder with the main package xml as packagename.xml and all of the resources inside the folder, with a directory structure if necessary (so you can have images/game/pic.png). Upon installation, all resources will be unpackaged in getMudletHomeDir()/packagename/.
Note: Mudlet by design allows duplicate item names, and the API works on all matching items. The same will be with the package system - ie., if you have two trigger folders named "my stuff", both of them will be included in the package.
Management
We'll most likely come up with an another tab, Packages, right after Scripts to deal with package management. More on this mockup later.
Versioning
A simple versioning algorithm will be available in Mudlet that will be able to warn the user if the package they are installing is an older version of what they have already / check for updates from some online repository. Packages will be able to define their own function for versioning if they'd like more advanced checking.
Storage
Packages, by design, thus will be 'stored' embedded in a users profile xml, just like triggers and etc. currently are - package data will be stored as a separate <PackagePackage> entry that will detail the package name, version as a string (default is 1 and by default will be auto-incremented by Mudlet), date of creation, author, website (optional) along with what trigger, aliases, etc. groups are 'included' in the package.
Installing
The same current 'import' button will import a package.
If there are any external resources included with the package, they will be unpacked in getMudletHomeDir()/packagename/, preserving their directory structure.
Upgrading
If the package has a name that is the same as of a package installed already, the previous package will be uninstalled simply and the new package will be installed.
If there are any external resources included with the package, previous resources will be wiped. New ones will be unpacked in getMudletHomeDir()/packagename/, preserving their directory structure.
Downgrading
Same as upgrading, but will visually warn the user of the downgrade, and should they proceed, uninstall the current package and install the new older version.
Downgrades are mentioned explicitly because they should be well-supported - scripts arguably undergo less testing than program releases, and messups can happen often. It's best not to frustrate the user more by making downgrading complicated - it should be a smooth process.
Uninstalling
All groups that the package claims belong to it will be deleted, and the package meta-information will be deleted. Persistent data saved on the disk by Lua scripts will be left intact, however. Lua objects (variables/functions) will stay in the user's session until the profile is restarted.
Before deleting scripts, a sysPackageUninstall <packagename> event will be raised such that the package can delete its temp* things, if there are any.
If there are any external resources included with the package, they will be preserved on-disk.
Completely uninstalling
Same as uninstalling, except a sysPackageCompleteUninstall <packagename> will be raised, giving the script a chance to delete the persistent data it saved on disk.
If there are any external resources included with the package, they will be erased from the disk, and the getMudletHomeDir()/packagename/ folder will be wiped.
Creating a package
Script-based method:
Package metadata will be also stored in the mudlet.packages table.
Appendix
Versioning algorithm
The versioning algorithm will distinguish between simple numeric releases - 1,2,3,... and dot-separated releases - 0,1, 1.0, 1.1, 2.0, etc...
It is possible that we'll expand it to better checking in the future.
Custom versioning function
If you'd like to use your own version comparison function, you can provide it's location as a string in the package metadata. The function will be given the current package version and the new package version to compare - it'll return true if it's newer, false if it's older, or nil if it couldn't decide (which will be the same as true).
For future releases:
- a way to view triggers/aliases/etc by package only
- a UI way to create the package contents and build it
A big thank you to all contributors to the discussion so far who suggested many excellent ideas for this base!
This post will kept updated to the current decided-upon state of the system as suggestions come.