Use case points for GiftWrap[]
Packaging GiftWrap plugins[]
What does this do: packages a giftwrap plugin as a .deb.
Packaging binary-only programs[]
What this does: installs a .desktop & moves a bunch of files around.
Packaging PPA installation .debs[]
What this does: Creates a .deb that adds a PPA to the users sources list & fetches a key.
Packaging kernel modules[]
What this does: packages a kernel module (most typically a driver)
Packaging themes[]
What does this do: place wallpapers, metacity themes, emerald themes into a package
- User selects the type of package (theme) to package
- User adds all of the requires folders
- GiftWrap copies it to a temporary location, such that the original archive can be deleted while being worked on
- User selects if package is to be installed system-wide or local
- this has several implications:
- if system-wide, then we need to setup the correct permissions for reading/applying the theme. I think the user also will not able to just delete it, since Ubuntus theme packages don't allow it (have to remove the package)
- if local, need to detect and install for the proper user, and remember this too - since admin is removing the package, we remove the proper local files.
- this has several implications:
- User fills in if any of the required information is missing
- Selects to build the package
- Take the steps necessary to build the package
- If something fails because of a missing package, see if we can detect which (apt-file helps), offer to install if what
- Done - offer to install the generated package, also allow user to open a folder with it (or generally, know where the .deb is located)
Packaging programs[]
What does this do:
- User selects the type of package (program) to package
- User selects a program archive or a source folder to package
- GiftWrap copies it to a temporary location, such that the original archive can be deleted while being worked on
- Get the file listing from the archive
- Analyze package and detect:
- Steps needed to compile it, if any
- Packages needed to compile it / runtime (Build-Depends and Depends)
- User fills in if any of the required information is missing
- Selects to build the package
- Take the steps necessary to build the package (these will be different even for compiling programs because of different build systems)
- If something fails because of a missing package, see if we can detect which (apt-file helps), offer to install if what
- Done - offer to install the generated package, also allow user to open a folder with it (or generally, know where the .deb is located)
Pieces of info to consider[]
Plugin system[]
The plugin system will serve as a "catch-all" mechanism in the program for parts which can have infinitely many ways of being done - like build systems (autotools, cmake, qmake, scons, waf, etc.). This will allow contributors to easily add support for a new method.
We can split them into two types - specialized and general.
Specialized will serve a specific tasks - right now, it's either a) preparing a certain type of package, or b) using different build systems for compiling programs.
General would do "anything" - ie, Launchpad integration could be a general plugin (and should be - people on other distros most likely won't want it and will complain)
Plugin ↔ Core interaction
They Core passes iterates through all the plugin asking them if they can build the source package. The core will then pass the plugin all the data it needs. The core will then grab the location of a ui file that
the plugin supplies for extra options. All plugins will have a "build" method that prepares the package for conversion into a deb. The plugin will notify the core about what it is doing via gobject signals.
Saving / loading[]
Format XML-like structure. This allows flexibility and would need to use just one file, instead of the debian/ folder way where information is stored in separate, some generated files.
Use cases on what needs to be serialized:
generic info program name, version, short description (several words), long descritiption (can have paragraphs), homepage link, package dependency metadata[1] and architecture.
plugin specific:
source-program: build system used (why no autodetect each time - autodetection might fail and user would need to set manually, and we need to remember that). Plus any customizations to generated debian/ files, but these possible will be stored as .patches that we'll apply.
theme: the type of each source file (which is a theme pack, wallpaper, etc) so we know where to install them.
How to do loading:
- pass all children of the <pluginname-plugin> tag to a plugin
How to do the loading:
- request the its portion of the xml file from a plugin and stuff it into the main one
In general, there won't be overlapping information, so using a <pluginname-plugin> or some similar tag and letting the said plugin load all children will work out fine.
Random notes[]
- Add the packages to be built into a queue, for now we'll just allow only one - but in the future, multiple builds might make sense. So given a queue, take the first item and use that. When we have multiple, go through each item in queue.
- Need to clearly separate the GUI from the core (rationale: people will want to reimplement the interface in other toolkits)
- Need to separate configuration file saving (gconf is good but it doesn't exist everywhere)
- Need to add a clear and informative error reporting, which should be included in all stages of process.
- can make use of https://launchpad.net/libdesktop-agnostic for config saving / .desktop generation. lda is in development and maturity is planned in august, so might have to go with a temporary GKeyFile solution for now.
- We should never block the interface with actions that might take a while to prevent 'freezing'.
- If an action is taking too long to do, we should provide a progress bar at the bottom, with an option to cancel [2]
Design so far[]
Objects used[]
- A class per window
- A plugin per build system
- The "core" - will have the actual application logic
- The project - project-specific metadata (https://blueprints.launchpad.net/giftwrap/+spec/main-project-class)
- each plugin will store its plugin-specific into in its own private object
- The core does validation of inputs and situations, and communicates with the gui
Program Flow[]
- gui loads xml, shows window
- gui creates instance of core class
- If it's a new project, typical program - add a 'build system used' label with a combobox offering all available plugins (with sane names) field
- when the user selects a folder / archive with sources,
- copy the sources to ~/.local/share/giftwrap - if it's an archive, then extract into there
- sic all plugins on it to detect the build system
- the selected plugin will emit a signal, and a callback in the gui will receive the info with the steps that need to be taken for building. The process treeview will be filled in with the info
- user fills in all of the metadata info, which is stored in the project object
- when done, we call the plugin to build, and give it the project object - so it pulls all the info needed for building from it
Packages[]
There are many different types of packages that we can't really account for. Besides the most popular of providing a program, there are also theme packs, game packages (with images/maps/sounds usually split into a -data package to save space), program plugins, binary-only packages, ppa-adding packages and etc. With so many different possibilities, it only makes sense to allow this to be pluggable. The method of "plugging in" rather than "patching" in such situations has been proven over and over to be more successful in attracting third-party contributions and making everyones - the main developers, contributors, and end-users lives easier.
Additionally, there are different methods of compiling the source packages themselves due to different build systems.
All giftwrap projects for 0.2.0 need to be serializable and deserializable.
Notes relevant to the implementation[]
We'll have to make the different package types as plugins, and have the program-from-source plugin have a plugin system of its own for the different package types (or integrate with the main one somehow, perhaps by emitting signals that its plugins can hook into, and this they can be loaded as all other plugins).
A plugin would, at minimum, provide a .ui file for us to load in which the user will specify the source(s) for the package. This'll be loaded in a separate tab. A plugin can additionally request more tabs and place more things in them as necessary.
A plugin would also need to be able to save/load all of it's information easily. While the generic metadata can be dealt with by the core, it would also need to save the plugin-specific fields.
So what needs to be decided: how to deal with plugins. Use raw gobject, or some framework? Existing ones are: http://git.dronelabs.com/ethos/, ...
How to deal with keeping the 'project' object, which will need to have fields that are added by plugins themselves?