Trac Object Model Proposal
This proposal is about unifying the capabilities of the various Trac objects, by making them inherit from a common TracObject class. The goal is to expand the feature set of Trac while simplifying its implementation.
What is Trac?
Trac is a a minimalistic approach to web-based software project management. To that end, it features an enhanced wiki and issue tracking system.
The tight and coherent integration of its features is achieved by several means, but most notably by the consistent use of a unified language to talk about objects in the system (the TracLinks). This unique approach enables a powerful structuring of the information in the system, yet this can be achieved in a very flexible and informal way.
In this light, Trac is a semi-structured Wiki, where one can create and modify objects and talk about them
Trac Object Model
In the following, I'll try to show that Trac is a manager for typed pieces of informations: the Trac objects.
There are many advantages to gain by refactoring the internals of Trac to acknowledge this reality:
- more consistency, less redundancy, code simplication
- spreading the features available for one object to the other objects
This updated revision is made in light of the experience gathered while working on the TracCrossReferences feature: for implementing generalized back links, I had to have a common interface to all the Trac objects, this was a practical reason to introduce the TracObject (see source:sandbox/trac-xref/trac/object.py).
What can be considered a Trac object (TracObject) are:
- wiki pages (WikiPage)
- tickets (Ticket)
- changesets (Changeset)
- milestones (Milestone)
- reports (Report)
- sources (Source)
Current State in trunk
Today, the various Trac objects are quite distinct objects. There is no code sharing between what defines objects and also not so much in the related modules that manipulates objects.
Indeed, those objects have distinct features. But some degree of unification would actually make sense, both in term of increased functionality and in term of decreased code complexity.
Last discussed examples were the ability to add comments on various objects, (this thread, ticket #2035), the ability to query over other objects than just the tickets (#2465), and several other examples (query:keywords~=object).
Toward an Unification
What would be a generic Trac object?
- It would have a unique identity in the system This would be the type and id properties.
- It would have some wiki syntax to describe it
- It would be displayed in several ways:
- a canonical form — fqname() e.g. wiki:WikiStart
- a shortcut form — shortname() e.g. WikiStart
- a display name — displayname() e.g. Ticket #123
- It should be addressable
- href() method
- anchor() method
- There could be one or several Wiki text attached to the object.
Each would be a facet of this object (FIXME I'm looking
for a better name than facet)
Some facets are:
- content, appropriate for a WikiPage and a Changeset
- description, appropriate for a Ticket, a Report and a Milestone
- comment:n for the nth comment
- There would be some fields attached to it.
- Some would be always there for the particular type of object considered
- Some would be custom properties
- One would want to be able to attach files to any object
- One would want to be able to comment on any object, just like for a Ticket
- One would want to see the history of the modification of the object
- the edit history of the main facet (like the Page History for a Wiki page)
- the change history of the value of the fields (like the Change History for a Ticket)
Let's compare these generic features with those of current Trac objects and see what additional functionality and usages it would provide.
The Wiki Page object would gain the ability to have custom fields.
The changeset message can be considered to be a facet for that object. Editing the message would be handled very similarly to editing the wiki page content (see #781). It will be versioned, like the content for wiki pages are.
If the underlying VersioningSystemBackend supports it, the change could be reflected in the repository itself (not all versioning systems support that: e.g. SVN does, Mercurial does not). A resync operation would simply add a new revision for the message, if something changed.
Custom properties could be used for many things, as a way to annotate the revision. Some ideas are:
- a boolean compilable flag (true by default, could be set to false to indicate that this revision can't be built)
- a field indicating the % of successful test cases
- a QA status
Attachments for a changeset also make sense:
- in case of a build failure, the corresponding errors from the compiler could be attached.
- patches that applies to that revision
The contributed comments could be used for code reviews
It would also be nice to be able to query changesets (see #2465).
There's currently no way to have an history of the description facet. Otherwise, the Ticket has pretty much all of the generic functionality.
There's also the question of having greater flexibility for ticket fields:
- different sets of fields for different types of tickets (see #2464)
- less difference between custom ticket fields and normal ticket fields (some kind of unification would be great here)
- possibility to have multiple values for a field (see #221, #918 and #1730)
There's also the question of bringing together Milestone and Ticket objects for implementing SubTickets.
Currently, there's no facet attached to a source. One could imagine having a summary or description facet. This could give a repository browsing experience close to what Sun did for OpenSolaris.
SOAP/REST support, permissions and security, in TRAC Objects could allow interface to remote resources and distributed functionality.
I'm not completely sure about what Jim meant in the above, but there's certainly a connection between this proposal and the security aspects, as can be seen in Alec's permission policy proposal.