Re: [zi-dev] RFC: Plugins Architecture

Sandro Zic <[email protected]> Fri, 23 Jan 2004 19:48:41 +0100
Newsgroups gmane.comp.php.zzoss.installer.devel
Organization ZZ/OSS GbR
Message-ID <[email protected]>
On Thursday 22 January 2004 19:21, Christian Zonsius wrote:
> >Customized plugins defined in an application.xml, overwrite conditions
> >defined
> >by the default plugins. This means that a customized plugin can overwrite
> > the way that a file with the role "php" (defined in the package.xml) is
> > processed. It can of course also introduce new file roles that it
> > handles.
>
> Can a customized plugin (e.g. com.zzoss.zic.plugin.filerole.myfilerole)
> extend the way, the file role attribute is handled ? Or does a customized
> file role plugin always replace the complete way the file role attribute is
> handled ?

It could extend it in a way that it includes or overwrites the routines aka 
methods of e.g. a default role like "php".

> >* Separating plugins from packages
> >
> >Basically, the new architecture is about separating plugins from packages.
> >
> >Up to now, plugins are defined within the application.xml element
> > <packages>. I would like to define plugins instead in a new <plugins>
> > element:
> >
> ><plugins>
> >         <plugin name="com.example.plugin.filerole" rel="ge"
> > version="1.0.0"/> </plugins>
>
> How does com.example.plugin.filerole look like ? Is this a classic package
> (with package.xml) for the installer like the one from
> com.zzoss.zic.plugin.filerole ?

A plugin is actually a package with the purpose of being a plugin within the 
installer. In another context, the same package may not be a plugin, but a 
class library or module of some other application.

> >This way, the installer can clearly detect required plugins and install
> > them into its framework before the packages are processed by those
> > plugins. Also, the installer can look up if a plugin meeting the
> > dependency requirements (rel, version) is already installed.
>
> Can a plugin have dependencies ? If yes, to what (other plugins or
> packages) ? What if a plugin got a dependency to another plugin/package,
> which throws some config form (= use some other plugins) ?

That's a good point. Due to the fact that plugins need to work self-contained, 
it should be able that they can form kind of little applications themselves, 
which means that they can define dependencies to other plugins, which might 
just be a class system like PEAR::DB and the corresponding package 
db-x.x.x.tgz.

This means, that plugins are basically handled like packages in the 
application.xml, the difference is that they are related to another 
"namespace" because they become part of the installer, and not of the 
application being installed. Hence, all plugins must be defined within the 
<plugins> element of the application.xml, which are needed to resolve 
dependencies - just like packages within the <packages> element.

> If we would allow a plugin to have dependencies to other plugins _and_
> packages, we have to distinguish between the way, those dependencies are
> solved.
> a) Packages: If a plugin got a package dependency, the package should be
> installed under some kind of plugin root, since all packages are requested
> by the plugin and not by the application.

That's partly right, just the terminology is misleading. As I mentioned, the 
plugin root is within the application's root in the installer data directory. 
Hence, plugins are installed per application and cannot make use of plugins 
installed for another application.

Be careful with the terminology! To keep things separate, it is clearer to 
speak of plugins depending on other plugins. Of course, a plugin is just a 
package, but we should distinguish them from those packages installed by the 
installer for an application by naming them due to their role: being a plugin 
of the installer. We could also talk about "plugin packages" and "application 
packages".

> b) Plugins: If a plugin got a plugin dependency, the plugin is installed by
> the installer (with version number, since it is possible that different
> packages/plugins use different versions of plugins)

Given the above mentioned terminology, plugins can only have dependencies on 
other plugins, but not on application packages - just to make things clear.

There's a problem I see with the fact that some application packages might 
need different versions of the same plugin to get installed properly: 
Currently, this is achieved by storing plugins in a directory with the plugin 
name and version, e.g.

com.example.plugin.filerole-1.0.0/

If another plugin depends on the above plugin and wants to include a file from 
it, it would have to keep track of the plugin version, doing a file include 
like

require_once 'com.example.plugin.filerole-1.0.0/include_file.php';

which becomes too much of an effort if the version of the plugin changes. Then 
all includes need to be changed.

Thus it would be best, to deal with it by omitting the version number in the 
future.

Then, we have to deal with plugins that are build from packages, especially 
classes, that install their files to subdirectories, like e.g. 
com.zzoss.error.lib:

[plugin-root]/com.zzoss.error.lib/ZZOSS_Error/Error.php

It would be natural for a plugin developer, to include the error class with

require_once 'ZZOSS_Error/Error.php';

That's what he is used to from PEAR - and that's the way that Error.php would 
include other classes that it depends on.

So why not, again, deal with installer plugins just like with application 
packages and define in the application.xml the location where to install a 
plugin within the plugin root with a baseinstalldir attribute:

<plugins>
	<plugin
		name="com.example.plugin.filerole"
		rel="ge"
		version="1.0.0"
		baseinstalldir="com.example.plugin.filerole/"
		/>
	<plugin
		name="DB"
		rel="ge"
		version="1.2"
		baseinstalldir="lib/"
		/>
</plugins>

I think, that's the way how to handle the problems of self-contained plugins 
that might also depend on other plugins and furthermore that plugins should 
easily be build from the same packages as those used by the installed 
application.

Implementation of this system would simply mean to use the existing routines 
for the installation of applications for plugins.

> So installing an application means "plugin download => optionally config of
> plugin (plugin uses another plugin) => plugin process" and afterwards
> "packages download => optionally packages config => packages process". If
> these two processes are executed one another (so steps of installer plugins
> + step of packages), the user would recognize it only as one or two
> additional steps when installing an application.

If we decide to handle installer plugins technically like installing an 
application, then it is the same process like installing the packages 
belonging to an application.

> >This approach most notably accounts for the different character of
> > plugins: they do not have dependencies to other plugins or packages, they
> > are always required and never optional once they are defined, and most
> > importantly: plugins are a part of the installer, not of the application.
> > They are just a mean to install the application, not to provide the
> > run-time routines of it.
>
> This means, that customized plugins by an application are afterwards
> "usable"  by any application since it is stored in the "global installer
> plugin repository" ?

No, customized plugins are only available for the application that defined the 
plugins in its application.xml. Customized plugins used by one application 
cannot be used by another one. This separation is necessary because the 
general approach of the installer is that of heterogeinity, i.e. there are no 
globaly valid package names: packages with exactly the same names and 
versions might contain completely different files out there in the Web. It's 
within the application.xml where they play a certain role for a certain 
application.

> >* Installing plugins
> >
> >In general, customized plugins are handled per application. This means, if
> >two
> >applications use the same customized plugin, the installer does install
> > the plugin for each application separately. It is only the default
> > plugins that ship with the installer that are used for any application
> > without installing them again for each installation.
>
> So the installer got one default plugin directory, one cached plugin tgz
> directory (if a application requests a plugin which is already available)
> and one plugin directory per application ?

Not exactly: downloaded and installed plugins are handled per application and 
totally separated from plugins of other applications.

> ><input>
> >     <widget
> >         name="path"
> >         label="A plugin-specific path"
> >         variable="my_path"
> >         info="Just a sample."/>
> ></input>
> >
> >The respective paths can be specified during the installation process by
> > the user in the same mask where he defines the application baseinstalldir
> > path (application_settings.php). This means that the installer has to
> > (maybe download and) unpack every plugin and read the input.xml
> > descriptor of each plugin specified in the application.xml in the
> > application_settings.php file.
> >
> >Those paths are stored in a global variable, e.g.
> >
> >$GLOBALS['ZI']['plugins']['com.example.plugin.filerole']['my_path']
> >
> >which is accessible by the plugin routines.
>
> can e.g. the filerole plugin access a value entered by the user in the
> config plugin ?

No, because the filerole plugin has only access to application wide data, 
which are those entered in application_settings.php. And this is why we need 
the above described input.xml in the root of the plugin's source, because the 
input widgets are displayed in application_settings.php to ask the user for 
application wide paths.

The config plugin starts at another point of the installation process, i.e. 
after the filerole plugin has done its job. There are currently three types 
of plugins: file role plugins ("role"), dependency plugins (not implemented 
yet, will be in 1.1.0, "dep"), and build plugins (like the config plugin, 
"build"). The sequence of execution is:

1. dep, 2. role, 3. build

> if a plugin will use some routines of another plugin (e.g. filerole asks
> config plugin for a special value of some package config), we might
> introduce some kind of plugin sdk. this contains the basic methods for
> communication between plugin <-> installer and plugin <-> plugin in
> abstract form. maybe porting plugins and the zic itself to different
> platforms is easier by a defined plugin sdk instead of a php-specific
> "global var interface".

The SDK is certainly a good idea!

> >For the installer to be able to find the plugins.xml, it needs to be
> > defined in the applications.xml, just like the packages.xml, except for
> > the role "plugins":
> >
> ><descriptor role="plugins">http://www.example.com/plugins.xml</descriptor>
>
> sounds good.
> if the installer got a cached version of exact the same plugin (name and
> version) defined in plugins.xml, does it still download the plugin or use
> the cached for installing it to plugin directory of application ?

It cachies downloaded plugins only per application.

> >* Downward compatibility
> >
> >Of course, the new installer will also be able to deal with the way that
> >plugins have been handled before.
>
> handled before in installing or when requested by packages during
> installation ? are you sure you can combine this with the new zic plugin
> architecture ?

We'll see ;) If not, then we should make it a major release 2.0.0.

Thanks Christian!
Sandro



-------------------------------------------------------
The SF.Net email is sponsored by EclipseCon 2004
Premiere Conference on Open Tools Development and Integration
See the breadth of Eclipse activity. February 3-5 in Anaheim, CA.
http://www.eclipsecon.org/osdn