The unified diff between revisions [2596d25a..] and [58429606..] is displayed below. It can also be downloaded as a raw diff.

#
#
# patch "ChangeLog"
#  from [716957e41c1f04ae4755a0648c7516e3b7970306]
#    to [c19d5a4aa54ccbb20f776b2b282f8e17f68b6d2e]
#
# patch "mtn.py"
#  from [24bdc6cf0f2935b5768da503135c11c50f86e267]
#    to [60dee430345a7183b092fd315c003468ffd86e33]
#
# patch "release.py"
#  from [02cc0da3565aacac95c45cd3cfbf493253e14f59]
#    to [49ec725bbbc7ba5b5ab6dc30de45b0c612bf7190]
#
# patch "release.sh"
#  from [391895b5a7b99a5cd10b6f2cc0af4a51165c1e28]
#    to [ec43a21a12b704c364720958c4ad72bd931b7d9f]
#
# patch "viewmtn.py"
#  from [937a0bd5668fef8dee7cb44f7c1584d7052812f3]
#    to [7b4da2d6e174dbee0d81e4460856e7779773ad31]
#
============================================================
--- ChangeLog	716957e41c1f04ae4755a0648c7516e3b7970306
+++ ChangeLog	c19d5a4aa54ccbb20f776b2b282f8e17f68b6d2e
@@ -1,3 +1,10 @@
+2008-02-14  Grahame Bowland  <grahame@fugro-fsi.com.au>
+
+	* implement optional arguments, use this to
+	disable ignoring of suspend certs
+	* don't link to empty revisions (for revisions
+	without an ancestor)
+
 2008-01-16  Grahame Bowland  <grahame@fugro-fsi.com.au>

 	* fix a #filter.. #end filter error affecting
============================================================
--- mtn.py	24bdc6cf0f2935b5768da503135c11c50f86e267
+++ mtn.py	60dee430345a7183b092fd315c003468ffd86e33
@@ -43,7 +43,8 @@ class Revision(str):
         # special case that must be handled: empty (initial) revision ID ''
         str.__init__(v)
         self.obj_type = "revision"
-        if v != '' and not (revision_re_c.match(self) and len(self) == sha1_len):
+        self.is_empty = (v == '')
+        if not self.is_empty and not (revision_re_c.match(self) and len(self) == sha1_len):
             raise MonotoneException("Not a valid revision ID: %s" % (repr(v)))
     def abbrev(self):
         return '[' + self[:8] + '..]'
@@ -139,9 +140,25 @@ class Automate(Runner):

         return CleanRequest(self.__run(*args, **kwargs))

-    def __run(self, command, args):
-        enc = "l%d:%s" % (len(command), command)
-        enc += ''.join(["%d:%s" % (len(x), x) for x in args]) + 'e'
+    def __run(self, command, args, **kwargs):
+        def str_with_len(l, s):
+            l.append(str(len(s)))
+            l.append(":")
+            l.append(s)
+        parts = []
+        for k in kwargs:
+            # can't use a '-' as a named function argument
+            kd = k.replace('_', '-')
+            parts.append("o")
+            str_with_len(parts, kd)
+            str_with_len(parts, kwargs[k])
+            parts.append("e")
+        parts.append("l")
+        str_with_len(parts, command)
+        for x in args:
+            str_with_len(parts, x)
+        parts.append("e")
+        enc = ''.join(parts)

         # number of tries to get a working mtn going..
         for i in xrange(2):
@@ -155,7 +172,6 @@ class Automate(Runner):
                 debug("exception writing to child process; attempting restart: %s" % format_exc())
                 self.stop()

-        import sys
         def read_result_packets():
             buffer = ""
             while True:
@@ -372,7 +388,7 @@ class Operations:
                 yield Tag(stanza[1], stanza[3], stanza[5], branches)

     def branches(self):
-        for line in (t.strip() for t in self.automate.run('branches', [])):
+        for line in (t.strip() for t in self.automate.run('branches', [], ignore_suspend_certs="")):
             if not line:
                 continue
             yield apply(Branch, (line,))
============================================================
--- release.py	02cc0da3565aacac95c45cd3cfbf493253e14f59
+++ release.py	49ec725bbbc7ba5b5ab6dc30de45b0c612bf7190
@@ -1,4 +1,4 @@
-version='0.08'
+version='0.09'
 authors='''
 Authors:

============================================================
--- release.sh	391895b5a7b99a5cd10b6f2cc0af4a51165c1e28
+++ release.sh	ec43a21a12b704c364720958c4ad72bd931b7d9f
@@ -11,7 +11,7 @@ OUT="release.py"

 # generate the help file data
 OUT="release.py"
-RELEASE="0.08"
+RELEASE="0.09"

 echo -n > "$OUT"
 echo "version='$RELEASE'" > "$OUT"
============================================================
--- viewmtn.py	937a0bd5668fef8dee7cb44f7c1584d7052812f3
+++ viewmtn.py	7b4da2d6e174dbee0d81e4460856e7779773ad31
@@ -180,8 +180,16 @@ class DiffLink(Link):
         else:
             mode = "diff"
         self.relative_uri = 'revision/%s/' % (mode) + diff.from_rev + '/with/' + diff.to_rev
-        if diff.fname:
-            self.relative_uri += '/'+urllib.quote(diff.fname)
+        if isinstance(diff.fname, list):
+            # TODO: figure out a linking scheme for diffs of multiple files.
+            if len(diff.fname) > 0:
+                fname = diff.fname[0]
+            else:
+                fname = None
+        else:
+            fname = diff.fname
+        if fname is not None:
+            self.relative_uri += '/'+urllib.quote(fname)
         self.description = "diff"

 class DirLink(Link):
@@ -267,8 +275,11 @@ def revisions_for_template(revision, rev
             value = "Patch file %s (%s)" % (link(mtn.File(fname, revision)).html(), diff_links)
         elif stanza_type == "old_revision":
             old_revision = mtn.Revision(stanza[1])
-            old_revisions.append(old_revision)
-            value = "Old revision is: %s (%s)" % (link(old_revision).html(), link(Diff(old_revision, revision)).html())
+            if old_revision.is_empty:
+                value = "This revision is has no ancestor."
+            else:
+                old_revisions.append(old_revision)
+                value = "Old revision is: %s (%s)" % (link(old_revision).html(), link(Diff(old_revision, revision)).html())
         elif stanza_type == "add_file":
             fname = stanza[1]
             value = "Add file: %s" % (link(mtn.File(fname, revision)).html())
@@ -315,7 +326,7 @@ class ComparisonRev:
 class ComparisonRev:
     def __init__(self, ops, revision):
         self.revision = revision
-        self.certs = map (None, ops.certs(self.revision))
+        self.certs = list(ops.certs(self.revision))
         self.date = None
         for cert in self.certs:
             if cert[4] == 'name' and cert[5] == 'date':
@@ -427,7 +438,7 @@ class Index:

 class Index:
     def GET(self):
-        branches = map(None, ops.branches ())
+        branches = list(ops.branches ())
         divisions.calculate_divisions (branches)
         def division_iter():
             bitter = iter(branches)
@@ -467,7 +478,7 @@ class Tags:
 class Tags:
     def GET(self, restrict_branch=None):
         # otherwise we couldn't use automate again..
-        tags = map(None, ops.tags())
+        tags = list(ops.tags())
         if restrict_branch != None:
             restrict_branch = mtn.Branch(restrict_branch)
             def tag_in(tag):
@@ -633,15 +644,15 @@ class Changes:
     def file_get_last_changes(self, from_change, to_change, revision, path):
         def content_changed_fn(start_revision, start_path, in_revision, pathinfo):
             uniq = set()
-            parents = map(None, ops.parents(in_revision))
+            parents = list(ops.parents(in_revision))
             for parent in parents:
-                stanza = map(None, ops.get_corresponding_path(start_revision, start_path, parent))
+                stanza = list(ops.get_corresponding_path(start_revision, start_path, parent))
                 # file does not exist in this revision; skip!
                 if not stanza:
                     continue
                 # follow the white rabbit
                 current_path = stanza[0][1]
-                stanza = map(None, ops.get_content_changed(parent, current_path))
+                stanza = list(ops.get_content_changed(parent, current_path))
                 to_add = stanza[0][1]
                 uniq.add(to_add)
                 pathinfo[to_add] = current_path
@@ -915,7 +926,7 @@ class RevisionBrowse(RevisionPage):
             page_title += " of %s %s" % (branch_plural, ', '.join(branches))

         def cut_manifest_to_subdir():
-            manifest = map(None, ops.get_manifest_of(revision))
+            manifest = list(ops.get_manifest_of(revision))
             in_the_dir = False
             for stanza in manifest:
                 stanza_type = stanza[0]
@@ -955,7 +966,7 @@ class RevisionBrowse(RevisionPage):
                 if not certs.has_key(revision):
                     # subtle bug slipped in here; ops.cert() is a generator
                     # so we can't just store it in a cache!
-                    certs[revision] = map(None, ops.certs(revision))
+                    certs[revision] = list(ops.certs(revision))
                 return certs[revision]

             def _get_certinfo(revision):
@@ -1165,6 +1176,8 @@ def ancestry_graph(revision):
     dot_data = ancestry_dot(revision)
     # okay, let's output the graph
     graph_sha = sha.new(dot_data).hexdigest()
+    if not os.access(config.graphopts['directory'], os.R_OK):
+        os.mkdir(config.graphopts['directory'])
     output_directory = os.path.join(config.graphopts['directory'], revision)
     if not os.access(output_directory, os.R_OK):
         os.mkdir(output_directory)