Dear all,
Attached is a patch based on trac-0.10.3 containing some refactoring to
the versioncontrol module (not the svn backend though).
Here is a summary of the changes:
class Repository:
def get_revision(self, path, rev): return Revision
def get_node(self, path, rev): return Node
class Node:
self.path
self.rev
def get_revision(self): return Revision
def get_history(self, limit, stop_rev):return [Node, ...]
class Revision:
self.message
self.author
self.date
self.base_path # branch/repository base
def get_node(path): return Node
I currently have the browser and log almost completely working with the
new interface and the modified trac+bzr plugin but Im still far from ready.
I see plenty of calls to normalize_rev and normalize_path in the
trac.log. I would like to suggest removing the functions normalize_*.
The normalization would be done by the implementation of Repository in
functions like get_revision(path, rev) and get_node(path, rev). These
functions return objects of types Revision and Node and this objects
have members keeping the normalized values (you can see this approach in
the attached path). I would also like to clean up the interfaces and
make them simpler.
I really liked Christians suggestion to use
revision.get_changeset(path). The second way of getting a changeset
would be by calling repository.get_changeset(new_node, old_node).
Furthermore, I thought it might make sense to have the Changeset class
ONLY represent the changes (files) but NOT the revision (message, data,
author). I feel like a lot of refactoring can be done in
web_ui.changeset and I guess Ill start from there before further
refactoring the versioncontrol api.
Looking forward to your comments!
Regards,
Peter
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Trac
Development" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/trac-dev?hl=en
-~----------~----~----~----~------~----~------~--~---
Index: trac/versioncontrol/api.py
===================================================================
--- trac/versioncontrol/api.py (revision 4673)
+++ trac/versioncontrol/api.py (working copy)
@@ -178,6 +178,10 @@
"""
raise NotImplementedError
+ def get_revision(self, path, rev=None):
+ """Retrieve a Revision object of the node at path and rev."""
+ raise NotImplementedError
+
def get_oldest_rev(self):
"""Return the oldest revision stored in the repository."""
raise NotImplementedError
@@ -258,7 +262,37 @@
"""
raise NotImplementedError
+class Revision(object):
+ """Represents a revision from a repository."""
+
+ def __init__(self, base_path, rev_str, message, author, date):
+ self.base_path = base_path
+ self.rev_str = rev_str
+ self.message = message
+ self.author = author
+ self.date = date
+ def get_node(self, path):
+ """Retrieve a Node at the given path and this revision.
+
+ A Node represents a directory or a file at a given revision in the
+ repository.
+ """
+ raise NotImplementedError
+
+ def get_changeset(self, path):
+ """Retrieve a Changeset corresponding to the this revision and possibly
+ restricted to the given path."""
+ raise NotImplementedError
+
+ def get_properties(self):
+ """Returns the properties (meta-data) of the node, as a dictionary.
+
+ The set of properties depends on the version control system.
+ """
+ raise NotImplementedError
+
+
class Node(object):
"""Represents a directory or file in the repository at a given revision."""
Index: trac/versioncontrol/web_ui/browser.py
===================================================================
--- trac/versioncontrol/web_ui/browser.py (revision 4673)
+++ trac/versioncontrol/web_ui/browser.py (working copy)
@@ -93,12 +93,7 @@
# Find node for the requested path/rev
repos = self.env.get_repository(req.authname)
- if rev:
- rev = repos.normalize_rev(rev)
- # If `rev` is `None`, we'll try to reuse `None` consistently,
- # as a special shortcut to the latest revision.
- rev_or_latest = rev or repos.youngest_rev
- node = get_existing_node(req, repos, path, rev_or_latest)
+ node = get_existing_node(req, repos, path, rev)
# Rendered list of node properties
hidden_properties = self.hidden_properties
@@ -117,7 +112,7 @@
'href': req.href.browser(path, rev=rev),
'log_href': req.href.log(path, rev=rev),
'restr_changeset_href': req.href.changeset(node.rev,
- node.created_path),
+ node.path),
'anydiff_href': req.href.anydiff(),
}
@@ -142,6 +137,7 @@
# Entries metadata
info = []
+ revisions = {}
for entry in node.get_entries():
info.append({
'name': entry.name,
@@ -153,7 +149,10 @@
'log_href': req.href.log(entry.path, rev=rev),
'browser_href': req.href.browser(entry.path, rev=rev)
})
- changes = get_changes(self.env, repos, [i['rev'] for i in info])
+ # May not work correctly in root because two branches may have the
same rev:
+ if not revisions.has_key(entry.rev):
+ revisions[entry.rev] = entry.get_revision()
+ changes = get_revisions_properties(self.env, repos, revisions.values())
# Ordering of entries
order = req.args.get('order', 'name').lower()
Index: trac/versioncontrol/web_ui/log.py
===================================================================
--- trac/versioncontrol/web_ui/log.py (revision 4673)
+++ trac/versioncontrol/web_ui/log.py (working copy)
@@ -72,12 +72,11 @@
limit = LOG_LIMIT
repos = self.env.get_repository(req.authname)
- normpath = repos.normalize_path(path)
- rev = unicode(repos.normalize_rev(rev))
+ node = repos.get_node(path, rev)
+ rev = node.rev
+ node_history = node.get_history(limit+1, stop_rev)
if stop_rev:
- stop_rev = unicode(repos.normalize_rev(stop_rev))
- if repos.rev_older_than(rev, stop_rev):
- rev, stop_rev = stop_rev, rev
+ stop_rev = node_history[-1].rev
req.hdf['title'] = path + ' (log)'
req.hdf['log'] = {
@@ -96,42 +95,31 @@
if path_links:
add_link(req, 'up', path_links[-1]['href'], 'Parent directory')
- # The `history()` method depends on the mode:
- # * for ''stop on copy'' and ''follow copies'', it's `Node.history()`
- # * for ''show only add, delete'' it's`Repository.get_path_history()`
- if mode == 'path_history':
- def history(limit):
- for h in repos.get_path_history(path, rev, limit):
- yield h
- else:
- history = get_existing_node(req, repos, path, rev).get_history
-
# -- retrieve history, asking for limit+1 results
info = []
- previous_path = repos.normalize_path(path)
- for old_path, old_rev, old_chg in history(limit+1):
- if stop_rev and repos.rev_older_than(old_rev, stop_rev):
- break
- old_path = repos.normalize_path(old_path)
+ revisions = {}
+ previous_path = node.path
+ for node in node_history:
+ old_chg = 'modified' #\todo
item = {
- 'rev': str(old_rev),
- 'path': old_path,
- 'log_href': req.href.log(old_path, rev=old_rev),
- 'browser_href': req.href.browser(old_path, rev=old_rev),
- 'changeset_href': req.href.changeset(old_rev),
- 'restricted_href': req.href.changeset(old_rev,
new_path=old_path),
+ 'rev': node.rev,
+ 'path': node.path,
+ 'log_href': req.href.log(node.path, rev=node.rev),
+ 'browser_href': req.href.browser(node.path, rev=node.rev),
+ 'changeset_href': req.href.changeset(node.rev,
node.get_revision().base_path),
+ 'restricted_href': req.href.changeset(node.rev,
new_path=node.path),
'change': old_chg
}
if not (mode == 'path_history' and old_chg == Changeset.EDIT):
info.append(item)
- if old_path and old_path != previous_path \
- and not (mode == 'path_history' and old_path == normpath):
- item['copyfrom_path'] = old_path
+ if node.path and node.path != previous_path \
+ and not (mode == 'path_history' and old_path == normpath):
#this maybe is never avaluated
+ item['copyfrom_path'] = node.rev
if mode == 'stop_on_copy':
break
- if len(info) > limit: # we want limit+1 entries
- break
- previous_path = old_path
+ previous_path = node.path
+ if not revisions.has_key(node.rev):
+ revisions[node.rev] = node.get_revision()
if info == []:
# FIXME: we should send a 404 error here
raise TracError("The file or directory '%s' doesn't exist "
@@ -159,8 +147,7 @@
req.hdf['log.items'] = info
- revs = [i['rev'] for i in info]
- changes = get_changes(self.env, repos, revs, verbose, req, format)
+ changes = get_revisions_properties(self.env, repos,
revisions.values(), verbose, req, format)
if format == 'rss':
# Get the email addresses of all known users
email_map = {}
Index: trac/versioncontrol/web_ui/util.py
===================================================================
--- trac/versioncontrol/web_ui/util.py (revision 4673)
+++ trac/versioncontrol/web_ui/util.py (working copy)
@@ -26,21 +26,17 @@
from trac.versioncontrol.api import NoSuchNode, NoSuchChangeset
from trac.wiki import wiki_to_html, wiki_to_oneliner
-__all__ = ['get_changes', 'get_path_links', 'get_path_rev_line',
+__all__ = ['get_revisions_properties', 'get_path_links', 'get_path_rev_line',
'get_existing_node', 'render_node_property']
-def get_changes(env, repos, revs, full=None, req=None, format=None):
+def get_revisions_properties(env, repos, revisions, full=None, req=None,
format=None):
db = env.get_db_cnx()
- changes = {}
- for rev in revs:
- try:
- changeset = repos.get_changeset(rev)
- except NoSuchChangeset:
- changes[rev] = {}
- continue
-
+ properties = {}
+ for revision in revisions:
+ if not revision:
+ continue # \todo don't let Nones here
wiki_format = env.config['changeset'].getbool('wiki_format_messages')
- message = changeset.message or '--'
+ message = revision.message or '--'
absurls = (format == 'rss')
if wiki_format:
shortlog = wiki_to_oneliner(message, env, db,
@@ -62,14 +58,14 @@
shortlog = shortlog.plaintext(keeplinebreaks=False)
message = unicode(message)
- changes[rev] = {
- 'date_seconds': changeset.date,
- 'date': format_datetime(changeset.date),
- 'age': pretty_timedelta(changeset.date),
- 'author': changeset.author or 'anonymous',
+ properties[revision.rev_str] = {
+ 'date_seconds': revision.date,
+ 'date': format_datetime(revision.date),
+ 'age': pretty_timedelta(revision.date),
+ 'author': revision.author or 'anonymous',
'message': message, 'shortlog': shortlog,
}
- return changes
+ return properties
def get_path_links(href, fullpath, rev):
links = [{'name': 'root', 'href': href.browser(rev=rev)}]
@@ -95,7 +91,7 @@
def get_existing_node(req, repos, path, rev):
try:
- return repos.get_node(path, rev)
+ return repos.get_node(path, rev)
except NoSuchNode, e:
raise TracError(Markup('%s<br><p>You can <a href="%s">search</a> '
'in the repository history to see if that path '