#
# src - simple revision control.
#
+# TO DO: Bounds-check revno arguments
+#
import sys, os, subprocess, time
version = 0.1
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 = []
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:
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()
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:
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'...]
# 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,
"co": checkout_method,
"cat": cat_method,
"diff": diff_method,
+ "tag": tag_method,
}
if __name__ == "__main__":