Edgewall Software

Changes between Initial Version and Version 1 of TracDev/Proposals/ProjectLabels


Ignore:
Timestamp:
Jan 3, 2012, 4:57:53 AM (12 years ago)
Author:
olemis+trac@…
Comment:

Initial proposal for project labels (classifiers) complementing wiki:TracDev/Proposals/MultipleProject

Legend:

Unmodified
Added
Removed
Modified
  • TracDev/Proposals/ProjectLabels

    v1 v1  
     1
     2= Project classifiers (aka labels) = #Introduction
     3
     4  Consider merging this page with
     5  [wiki:TracDev/Proposals/MultipleProject Multi-Project Support for Trac]
     6
     7In order to provide an structured solution so as not to limit the possible ways of
     8grouping projects it is convenient to introduce the concept of
     9'''project labels'''. Main goals are the following :
     10
     11  - Offer a structured mechanism to identify a group of projects no matter
     12    what hierarchy is involved .
     13  - Encapsulate these details at the API level while
     14    determining (multi)project context.
     15
     16Considering the [wiki:TracDev/Proposals/MultipleProject#ProjectTree reference example],
     17in spite of searching for tickets
     18in `Family A` and `Family B` but not in `Tools` and `3rdParty` when needed,
     19a label containing both projects has to be created (either ''explicitly'' or
     20''implicitly'', see [#SpecialLabels below]) .
     21
     22This document also suggests alternatives and approaches to implement some
     23features defined in
     24[wiki:TracDev/Proposals/MultipleProject Multi-Project Support for Trac]. Some
     25content may actually overlap aforementioned specification.
     26
     27== URL space for different projects == #UrlMapping
     28
     29A constraint should be imposed in order to simplify dispatching strategy so as
     30to map projects to ''URL''s. Project short name '''MUST''' be unique in the
     31context of an environment.
     32
     33  - '''host mapping''': the name of the (virtual) host used to access the
     34    ''Trac'' environment is taken to be the name of the project. A given host
     35    can be configured to be an alias for the default, top-level project. Label
     36    names are not allowed to be used this way.
     37  - '''prefix mapping''': if the `PATH_INFO` starts with `/p/<project name>/`
     38    prefix, name of a project will be taken to be `<project_name>` . Otherwise if
     39    it starts with `/l/<label_name>/` then the request is addressed to the set
     40    of projects included in label `<label_name>`. In general this is less
     41    ambiguous than the
     42    [wiki:TracDev/Proposals/MultipleProject#URLspacefordifferentprojects mapping suggested in original proposal].
     43    Explanation and implementation details provided [#UrlExplained below].
     44
     45== The Data Model and the API == #DataModelApi
     46
     47Labels may be considered as resources bound to the environment rather
     48than to particular projects (e.g. like `Changeset` and `Source` which belong
     49to a given repository - see MultiRepos). Hence only an
     50additional `labels` table is also needed, and it can take the form of a
     51''resource table specialization'' from the GenericTrac. Project labels should
     52have at least short name (and maybe description) field. Project labels can be
     53linked explicitly to projects and labels (if using [#NestedLabels nested labels]).
     54These connections can take the form of ''relations'' from
     55[wiki:TracDev/Proposals/TracRelations Trac Relations].
     56
     57=== URL prefix mapping explained === #UrlExplained
     58
     59Project-specific URLs will start with `/p/<project name>` prefix.
     60Requests involving multiple projects will be made available on a per-label
     61basis at ''URL''s starting with `/l/<label name>` prefix. Remaining path after
     62this will be used to select what instance of `IRequestHandler` should process
     63the request. Examples below illustrate some use cases. In all cases 
     64multi-project environment root ''URL'' is `http://server.com/path/to/trac/` and
     65it will contain the reference project hierarchy used throughout this document :
     66
     67|| '''URL''' || '''Target projects''' || '''Comments''' ||
     68|| `http://server.com/path/to/trac/` || top-level project (i.e. `''` ) ||  ||
     69|| `http://server.com/path/to/trac/roadmap` || top-level project (i.e. `''` ) || Top-level milestone view. This may be used to show top-level (e.g. product, current year, ...) milestones. ||
     70|| `http://server.com/path/to/trac/p/FamilyB/roadmap` || project '''FamilyB''' || '''FamilyB''' project-specific milestones. ||
     71|| `http://server.com/path/to/trac/p/product_c/roadmap` || project '''product_c''' || '''product c''' project-specific milestones. ||
     72|| `http://server.com/path/to/trac/l/javascript/roadmap` || all projects in label '''javascript''' || display milestones for javascript projects. ||
     73
     74By doing things this way request dispatch may be implemented as a combination of
     75two existing architectural features , namely '''request filters''' and
     76'''request handlers'''. First of all by supporting multi-project
     77specifications the context associated to the request has to contain
     78information about target project(s) . One component acting as a request filter 
     79intercepts the request before match is performed. If any multiproject
     80prefix (i.e. `/p/<project name>` or `/l/<label name>`) is detected then
     81project resolution takes place. Single-project requests only
     82need to add corresponding internal project resource to context.
     83In the case of labels the context should contain ''label name'' as well as a
     84list of resources identifying target projects . In the case of
     85[#SpecialLabels more complex project selector expressions] the context should contain the
     86expression itself, the instance of `IProjectLabelManager` matching label name,
     87and the list of resource objects identifying target projects . If this
     88advanced feature will be supported, it may be considered as a generic way to
     89encapsulate multi-project context in spite of having flexibility and uniformity,
     90considering the fact that first two variants are just particular cases.
     91Aforementioned data may be retrieved right away at dispatch time or loaded
     92on demand.
     93
     94Immediately after multi-project context resolution, the request filter rewrites
     95`PATH_INFO` by removing project selection prefix. The request is then
     96matched as usual so as to determine the handler responsible for processing it
     97(e.g. `wiki`, `ticket`, ...). The target instance of `IRequestHandler` will
     98rely on request context so as to determine target projects involved and
     99build the response accordingly.
     100
     101== Advanced labels features == #LabelsAdvanced
     102
     103Subsequent sub-sections deal with some advanced features that may be useful
     104under certain circumstances but may also over-complicate core design .
     105Nonetheless I mention them here for the sake of
     106~~could not find the right word~~.
     107
     108=== Project alias === #LabelAlias
     109
     110A label related to a single project may be considered a project alias. This
     111scenario may happen when two or more projects are merged and previous project
     112name is to be kept so as not to break external references, for instance.
     113
     114=== Nested labels === #NestedLabels
     115
     116It might be convenient as well to provide a way to specify a hierarchy of
     117labels (rather than projects). In order to illustrate this with a particular
     118example which might be very common in practice, let's consider we have the
     119[wiki:TracDev/Proposals/MultipleProject#ProjectTree sample hierarchy of projects]
     120and still need to
     121group them according to programming languages and frameworks used to build
     122them (let them be explicit project dependencies or not). In that case it will
     123be useful to have some labels like `javascript`, `python`, `c#`, `vb.net`,
     124`f#`, `ruby`, `php` and so on. Let's also consider a similar situation
     125and project classification also includes frameworks, so there are further
     126tags like e.g. `trac`, `wcf`, `jquery`, `mootools`, `wpf`, `django`, `dojo`, ...
     127Nonetheless :
     128
     129  - It may be useful to know which projects are related to ''.NET framework''.
     130  - It may be useful to ease the process by tagging projects using a single
     131    label identifying a framework and having them auto-magically included in
     132    the label for the corresponding programming language .
     133
     134In order to do that the following label hierarchy might help :
     135
     136{{{
     137 +-- python
     138 | +-- trac
     139 | +-- django
     140 +-- ruby
     141 +-- javascript
     142 | +-- jquery
     143 | +-- dojo
     144 | +-- mootools
     145 +-- .net
     146 | +-- .net languages
     147 | | +-- c#
     148 | | +-- vb.net
     149 | | +-- f#
     150 | +-- .net technologies
     151 | | +-- wpf
     152 | | +-- wcf
     153 | | +-- wwf
     154 +-- php
     155 
     156}}}
     157
     158For instance , [http://trac-hacks.org Trac-Hacks] website may be one such
     159example where there's a flat one-level project hierarchy and labels to group
     160hacks. In [#TracHacksLabels Apendix B] it is possible to see
     161sample label hierarchy based on hack classifiers available at present. Idea
     162is , for instance, that if somebody tags a project using `macro` label then
     163it also belongs auto-magically in `plugins` label.
     164
     165There's another precision that needs to be mentioned up to this point and it
     166is whether it is more convenient to define label relationships using graphs
     167rather than a tree . Considering the same case mentioned above ,
     168labels like `iron_python` , `iron_ruby` would be hard to
     169classify considering aforementioned hierarchy as they may be related to both
     170`.net` and (`python` | `ruby`) (same reasoning for e.g. `jpype` , `jython` for
     171`python` & `java`; `rython` , `unholy` for `python` & `ruby` ... and it's
     172possible to find more examples even in totally different business domains).
     173
     174=== Project context extensions === #SpecialLabels
     175
     176It may be useful to be able to specify ''special'' project groups like :
     177
     178  - ''all parents of project A''
     179  - ''direct children of project B''
     180  - ''descendant of project C''
     181  - `*` all the projects (mentioned in [wiki:TracDev/Proposals/MultipleProject#URLspacefordifferentprojects original Multi-Project specification])
     182  - glob pattern (mentioned in [wiki:TracDev/Proposals/MultipleProject#URLspacefordifferentprojects original Multi-Project specification])
     183  - `!` prefix to exclude projects (mentioned in [wiki:TracDev/Proposals/MultipleProject#URLspacefordifferentprojects original Multi-Project specification])
     184  - comma-separated list of project names (e.g. `FamilyA,product_d,3rdParty`)
     185  - ''XPath expressions''
     186
     187These are just a few examples. In order to prepare the system for flexibilty
     188and maybe allow the definition of other project selector expressions (e.g. in
     189plugins) it is convenient to introduce a new interface
     190(namely `IProjectLabelManager`) used to determine which projects belong in a
     191given label, provided its name. Selection should work using a chain of
     192responsibilty similar to the one already used for `IRequestHandler`. All
     193instances of `IProjectLabelManager` are requested to expand a project selector
     194expression. This will consist of returning a list of project names ''matching''
     195a given label name (aka ''project selector expression'' <= this seems to be
     196more generic ''';)''' , or `None` if such match is not found. In the later case
     197the next instance of `IProjectLabelManager` is considered and so on ... until
     198either a match is found (and subsequent request handling takes place) or all
     199options are exhausted (and error handling occurs e.g. ''HTTP 404 Not Found''
     200returned to the client) .
     201
     202== User interface == #LabelsGUI
     203
     204Considering everything mentioned up to this point , the following variants of
     205project selector GUI control are suggested.
     206
     207=== Project selector (drop-down menu) === #LabelsMenu
     208
     209The use of labels makes possible to present a flat drop-down menu to the user
     210in order to select a set of projects like shown below. This may be considered
     211more appropriate than always having to display a hierarchy.
     212
     213{{{
     214#!html
     215
     216<select id="SampleProjectMenu" name="field_milestone">
     217  <option></option>
     218  <optgroup label="Projects">
     219    <option>Top-level</option>
     220    <option>Family A</option>
     221    <option>&nbsp;&nbsp;product a</option>
     222    <option>&nbsp;&nbsp;product b</option>
     223    <option>Family B</option>
     224    <option>&nbsp;&nbsp;product c</option>
     225    <option>&nbsp;&nbsp;product d</option>
     226    <option>Tools</option>
     227    <option>3rdParty</option>
     228  </optgroup>
     229  <optgroup label="Labels">
     230    <option>Product families</option>
     231    <option selected="true">Products</option>
     232    <option><i>Create new label ...</i></option>
     233  </optgroup>
     234</select>
     235}}}
     236
     237'''PS''': ''Create new label ...'' option should be visible only if user can
     238create labels. If the user can modify labels (i.e. classify projects in
     239categories) then it may be useful to include shortcut links to update projects
     240membership. In both cases a dialog (see picture below) should be displayed.
     241
     242{{{
     243#!html
     244
     245<div id="SampleLabelsEditor" style="width:50%;margin-left:auto;margin-right:auto;background-color:#666666;">
     246  <div style="background-color:#666666;color:#ffffff;">Create new label</div>
     247  <div style="background-color:#ffffff;padding:15px;">
     248   <label for="label_id">Label ID :</label>
     249   <input type="text" id="label_id"></input>
     250   <br/>
     251   <label for="label_name">Label name :</label>
     252   <input type="text" id="label_name"></input>
     253   <br/>
     254   <fieldset style="display: inline;clear:both;">
     255    <legend>Select projects</legend>
     256    <form>
     257     <ul style="list-style-type: none">
     258      <li>
     259      <input type="checkbox">Top-level</input>
     260      <ul style="list-style-type: none">
     261       <li>
     262        <input type="checkbox" checked="checked"><b>Family A</b></input>
     263        <ul style="list-style-type: none">
     264         <li><input type="checkbox">product a</input></li>
     265         <li><input type="checkbox">product b</input></li>
     266        </ul>
     267       </li>
     268       <li>
     269        <input type="checkbox" checked="checked"><b>Family B</b></input>
     270        <ul style="list-style-type: none">
     271         <li ><input type="checkbox">product c</input></li>
     272         <li><input type="checkbox">product d</input></li>
     273        </ul>
     274       </li>
     275       <li><input type="checkbox">Tools</input></li>
     276       <li><input type="checkbox">3rdParty</input></li>
     277      </ul>
     278      </li>
     279     </ul>
     280    </form>
     281   </fieldset>
     282   <br/>
     283   <button>Ok</button>
     284   <button>Cancel</button>
     285  </div>
     286</div>
     287}}}
     288
     289=== Project selector (tree view) === #LabelsTreeView
     290
     291Another option is to provide a more ellaborate version of the box suggested in
     292[wiki:TracDev/Proposals/MultipleProject Multi-Project Support specification].
     293One of the benefits is that it will be possible to select either projects or
     294labels. It should look like this
     295
     296{{{
     297#!html
     298<fieldset style="display: inline" id="SampleProjectTreeView">
     299 <legend>Project Selector</legend>
     300 <form>
     301  <ul style="list-style-type: none">
     302   <li>
     303    <input type="checkbox">Top-level</input>
     304    <ul style="list-style-type: none">
     305     <li>
     306      <input type="checkbox"><b style="background-color: #ffffcc;border:1px dashed #999999;">Family A</b></input>
     307      <ul style="list-style-type: none">
     308       <li><input type="checkbox">product a</input></li>
     309       <li><input type="checkbox">product b</input></li>
     310      </ul>
     311     </li>
     312     <li>
     313      <input type="checkbox"><b style="background-color: #ffffcc;border:1px dashed #999999;">Family B</b></input>
     314      <ul style="list-style-type: none">
     315       <li ><input type="checkbox">product c</input></li>
     316       <li><input type="checkbox">product d</input></li>
     317      </ul>
     318     </li>
     319     <li><input type="checkbox">Tools</input></li>
     320     <li><input type="checkbox">3rdParty</input></li>
     321    </ul>
     322   </li>
     323  </ul>
     324  <ul style="list-style-type: none">
     325   <li style="background-color: #999999; color: #ffffff">
     326    <input type="checkbox" checked="checked"><b>Product families</b><a href="#SampleProjectTreeView" style="font-size:11px;margin-left:3px;">Edit</a></input>
     327   </li>
     328   <li style="background-color: #CCCCCC">
     329    <input type="checkbox">Products<a href="#SampleProjectTreeView" style="font-size:11px;margin-left:3px;">Edit</a></input>
     330   </li>
     331   <li style="background-color: #999999; color: #ffffff">
     332    <input type="checkbox"><b>All except product b</b><a href="#SampleProjectTreeView" style="font-size:11px;margin-left:3px;">Edit</a></input>
     333   </li>
     334   <li>  <button>New label ...</button> </li>
     335  </ul>
     336 </form>
     337</fieldset>
     338}}}
     339
     340Once label is selected then target projects should be highlighted like above.
     341
     342Ideally it should be possible to drag a project & drop it on an item
     343representing a label in order to add that project to that label (a confirmation
     344box may be shown so as to detect mistakes).
     345
     346Label membership editor dialog box may be displayed as well so as to edit a
     347label if user clicks on ''Edit'' link.
     348
     349== Appendix A : Other systems supporting labels == #SimilarSystems
     350
     351Other similar examples of the use of labels in other products are :
     352
     353  - [http://support.google.com/plus/bin/answer.py?hl=en&answer=1047805&topic=1257347&ctx=topic Google+ circles] which allow to group people,
     354  - ''GMail contact groups'' which serve to a similar purpose
     355  - ''GMail labels'' which allow to mark e-mails
     356
     357Other instances of similar label hierarchies :
     358
     359  - ''GMail'' nested labels.
     360
     361== Appendix B : Proposed label hierarchy for Trac-Hacks == #TracHacksLabels
     362
     363This section considers just a subset of
     364[http://trac-hacks.org Trac-Hacks] classifiers.
     365
     366{{{
     367
     368 +-- supported-version
     369 | +-- 0.1
     370 | +-- 0.10
     371 | +-- 0.10.4
     372 | +-- 0.11
     373 | +-- 0.11.5
     374 | +-- 0.11.6
     375 | +-- 0.12
     376 | +-- 0.12-compatible
     377 | +-- 0.12dev
     378 | +-- 0.13
     379 | +-- 0.3.4
     380 | +-- 0.4
     381 | +-- 0.5
     382 | +-- 0.5dev
     383 | +-- 0.8
     384 | +-- 0.9
     385 | +-- 0.9.1
     386 | +-- 0.9.2
     387 | +-- 0.9.6
     388 | +-- 1.1dev
     389 | +-- trunk
     390 | +-- anyrelease
     391 +-- db
     392 | +-- sql
     393 | +-- sqlalchemy
     394 | +-- sqlite
     395 | | +-- sqlite3
     396 | +-- postgresql
     397 | +-- mysql
     398 +-- plugin
     399 | +-- macro
     400 | +-- theme
     401 +-- scripts
     402 +-- patch
     403 +-- integration
     404 +-- translation
     405 +-- workflow
     406
     407}}}