]> thyrsus.com Git - src.git/commitdiff
We can set and parse symbols.
authorEric S. Raymond <esr@thyrsus.com>
Fri, 7 Nov 2014 03:33:38 +0000 (22:33 -0500)
committerEric S. Raymond <esr@thyrsus.com>
Fri, 7 Nov 2014 03:33:38 +0000 (22:33 -0500)
src

diff --git a/src b/src
index 1fc3d0aa8d80554c4b5d58b26a6468d8166055c5..bcf248f7ff4913a668577571ada56a2f825e5649 100755 (executable)
--- a/src
+++ b/src
@@ -2,6 +2,8 @@
 #
 # src - simple revision control.
 #
+# TO DO: Bounds-check revno arguments
+#
 import sys, os, subprocess, time
 
 version = 0.1
@@ -94,7 +96,7 @@ class RCSLog:
     def __init__(self, name):
         self.name = name
         self.revlist = []
-        self.symbols = []
+        self.symbols = {}
         with popen_or_die("cd .src >/dev/null; rlog %s; cd ..>/dev/null" % name) as fp:
             self.revlist = []
             self.lockrevs = []
@@ -110,16 +112,16 @@ class RCSLog:
                         if debug >= DEBUG_PARSE:
                             sys.stdout.write("\t-> locks\n")
                         state = "locks"
-                    elif line.startswith("symbols:"):
+                    elif line.startswith("symbolic names:"):
                         if debug >= DEBUG_PARSE:
                             sys.stdout.write("\t-> symbols\n")
                         state = "symbols"
-                elif line.startswith("----------------------------"):
-                    if debug >= DEBUG_PARSE:
-                        sys.stdout.write("\t-> logheader\n")
-                    state = "logheader"
-                    self.revlist.append(RCSRevisionItem(self, maxrevno))
-                    maxrevno += 1
+                    elif line.startswith("----------------------------"):
+                        if debug >= DEBUG_PARSE:
+                            sys.stdout.write("\t-> logheader\n")
+                        state = "logheader"
+                        self.revlist.append(RCSRevisionItem(self, maxrevno))
+                        maxrevno += 1
                 elif state == "locks":
                     if not line[0].isspace():
                         if debug >= DEBUG_PARSE:
@@ -128,14 +130,18 @@ class RCSLog:
                     else:
                         fields = line.strip().split()
                         self.lockrevs.append(fields[1])
-                elif state == "symbolic names":
+                elif state == "symbols":
                     if not line[0].isspace():
                         if debug >= DEBUG_PARSE:
                             sys.stdout.write("\t-> init\n")
                             state = "init"
                     else:
                         fields = line.strip().split()
-                        self.symbols.append(fields[1])
+                        name = fields[0]
+                        if name.endswith(":"):
+                            name = name[:-1]
+                        rev = fields[1]
+                        self.symbols[name] = rev
                 elif state == "logheader":
                     if line.startswith("revision"):
                         fields = line.split()
@@ -156,11 +162,15 @@ class RCSLog:
             for item in self.revlist:
                 item.revno = maxrevno - item.revno
             if debug >= DEBUG_PARSE:
+                print "\t%d revisions" % len(self)
                 print "\tlockrevs:", self.lockrevs
+                print "\tsymbols:", self.symbols
     def __len__(self):
         return len(self.revlist)
     def __getitem__(self, i):
         return self.revlist[i]
+    def tip(self):
+        return self.revlist[0]
     def rcs_to_revno(self, revision):
         "Map an RCS ID to a revno"
         for item in self.revlist:
@@ -202,7 +212,7 @@ src cat [revspec] ['file'...]
 src branch [delete] ['branchname']
    Create, switch to, or delete a branch. With no arguments, list branches.
 
-src tag [delete] ['tagname'] ['revspec']
+src tag [delete] ['tagname'] ['revspec'] ['file'...] 
    Create, switch to, or delete a tag. With no arguments, list tags.
 
 src list ['revision-spec'] ['file'...]
@@ -382,6 +392,51 @@ def diff_method(*args):
             # The || : suppresses the error return from diff(1)
             do_or_die("rcsdiff -q {0} {1} {2} || :".format(diffspec, diffopts, arg),loud=True)
 
+def list_tags(args):
+    pass
+
+def delete_tags(args):
+    if not args:
+        croak("deleting tags requires a tagname argument")
+    tagname = args.pop(0)
+    (revspec, args) = preamble("tag", args)
+    if revspec is not None:
+        croak("can't accept a revision-spec when deletting tags.")
+    for arg in args:
+        with lifted(arg):
+            do_or_die("rcs -n{0} {1}".format(tagname, arg))
+
+def set_tags(args):
+    if not args:
+        croak("setting tags requires a tagname argument")
+    tagname = args.pop(0)
+    (revspec, args) = preamble("tag", args)
+    for arg in args:
+        state = RCSLog(arg)
+        if revspec is None:
+            revision = state.tip().revision
+        elif len(revspec) == 1:
+            revision = state.revno_to_rcs(revspec[0])
+        else:
+            croak("can't accept a range when setting tags.")
+        with lifted(arg):
+            do_or_die("rcs -N{0}:{1} {2}".format(tagname, revision, arg))
+
+def tag_method(*args):
+    "Inspect, create, and delete tags."
+    args = list(args)
+    if not args:
+        list_tags()
+        return
+    if args[0] == '--':
+        args.pop(0)
+    else:
+        deleteflag = args[0] in ("-d", "del", "delete")
+        if deleteflag:
+            set_tags(args[1:])
+            return
+    set_tags(args)
+
 dispatch = {
     "help":     help_method,
     "init":     init_method,
@@ -394,6 +449,7 @@ dispatch = {
     "co":       checkout_method,
     "cat":      cat_method,
     "diff":     diff_method,
+    "tag":      tag_method,
 }
 
 if __name__ == "__main__":