]> thyrsus.com Git - src.git/commitdiff
Most of the way to backend encapsulation. Regression test passes.
authorEric S. Raymond <esr@thyrsus.com>
Sat, 8 Nov 2014 17:07:39 +0000 (12:07 -0500)
committerEric S. Raymond <esr@thyrsus.com>
Sat, 8 Nov 2014 17:07:39 +0000 (12:07 -0500)
src

diff --git a/src b/src
index dc54a1bd14a2f74f7bb1aeec7c431c28b90641ab..cec4be1a108332cc61f483c65c2cd46e6d55850c 100755 (executable)
--- a/src
+++ b/src
@@ -33,8 +33,6 @@ DEBUG_PARSE     = 2    # Debug logfile parse
 quiet = False          # option -q: run more quietly
 pseudotime = False     # option -T: artificial clock for regression testing
 
-
-
 # Repo directory
 repodir = ".src"
 
@@ -114,9 +112,6 @@ class RCSRevisionItem:
         except TypeError, ValueError:
             croak("garbled date %s" % self.date)
 
-def master(arg):
-    return os.path.join(repodir, arg + ",v")
-
 class History:
     "Encapsulate a revision list and some methods on it"
     def __init__(self, name):
@@ -124,7 +119,7 @@ class History:
         self.revlist = []
         self.symbols = {}
         self.delimiter = None
-        if not os.path.exists(master(self.name)):
+        if not os.path.exists(backend.master(self.name)):
             croak("%s is not registered" % self.name)
         with popen_or_die("cd %s >/dev/null; rlog %s 2>/dev/null; cd ..>/dev/null" % (repodir, name)) as fp:
             self.revlist = []
@@ -387,10 +382,10 @@ def add_method(*args):
     for arg in args:
        if not os.path.exists(arg):
            croak("I see no '%s' here." % arg)
-       elif os.path.exists(master(arg)):
+       elif os.path.exists(backend.master(arg)):
            croak("%s is already registered." % arg)
        else:
-           do_or_die("rcs -q -kb -i {0} </dev/null && mv {0},v {1}".format(arg, repodir)) 
+           backend.add(arg)
            if not quiet and len(args) > 1:
               announce("%s -> 0" % arg) 
 
@@ -438,7 +433,7 @@ def commit_method(*args):
     for arg in args:
        if not os.path.exists(arg):
            croak("I see no '%s' here." % arg)
-       elif not os.path.exists(master(arg)):
+       elif not os.path.exists(backend.master(arg)):
            croak("%s is not registered." % arg)
        else:
            metadata = History(arg)
@@ -508,7 +503,7 @@ def checkout_method(*args):
         else:
             revision = master[len(master) - revspec[0]].revision
         with lifted(arg):
-            do_or_die("rm -f {0} && rcs -q -u {0},v && co -q -l{1} {0}".format(arg, revision))
+            backend.checkout(arg, revision)
         if not quiet and len(args) > 1:
             announce("%s <- %d" % (arg, revspec[0])) 
 
@@ -568,7 +563,7 @@ def delete_tags(args):
             croak("%s is not a tag in %s" % (tagname, arg))
         else:
             with lifted(arg):
-                do_or_die("rcs -n{0} {1}".format(tagname, arg))
+                backend.delete_tag(tagname, arg)
             if not quiet and len(args) > 1:
                 announce("tag %s removed from %s" % (tagname, arg))
 
@@ -589,7 +584,7 @@ def set_tags(args):
         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))
+            backend.set_tag(tagname, revision, arg)
             if not quiet and len(args) > 1:
                 announce("tag %s = %s in " % (tagname, revno, arg))
 
@@ -632,7 +627,7 @@ def fast_export_method(*args):
         useremail = capture_or_die("git config --get user.email").strip()
     attribution = "%s <%s>" % (username, useremail)
     for arg in args:
-        if not os.path.exists(master(arg)):
+        if not os.path.exists(backend.master(arg)):
             croak("%s is not registered" % arg)
         executable = os.stat(arg).st_mode & stat.S_IXUSR
         if executable:
@@ -655,7 +650,7 @@ def fast_export_method(*args):
                 branch = arg + "master"
             for revno in revrange:
                 scratchfile = "/tmp/src%dtmp" % os.getpid()
-                do_or_die("co -q -p -r{1} {0} >{2}".format(arg, metadata.revno_to_rcs(revno), scratchfile))
+                backend.cat(arg, metadata.revno_to_rcs(revno), scratchfile)
                 size = os.path.getsize(scratchfile)
                 mark += 1
                 markmap[revno] = mark
@@ -701,11 +696,10 @@ def moveto_method(*args):
     for arg in args:
        if not os.path.exists(arg):
            croak("I see no '%s' here." % arg)
-       elif not os.path.exists(master(arg)):
+       elif not os.path.exists(backend.master(arg)):
            croak("%s is not registered, skipping." % arg)
        else:
-           # Using mv(1) evades cross-filesystem issues
-           do_or_die("mv {0} {1} && mv {2} {3]/{4}".format(arg, target, master(arg), target, repodir)) 
+           backend.moveto(arg, target)
            if not quiet and len(args) > 1:
               announce("%s -> %s" % target)
 
@@ -726,11 +720,10 @@ def copyto_method(*args):
     for arg in args:
        if not os.path.exists(arg):
            croak("I see no '%s' here." % arg)
-       elif not os.path.exists(master(arg)):
+       elif not os.path.exists(backend.master(arg)):
            croak("%s is not registered, skipping." % arg)
        else:
-           # Using cp(1) evades cross-filesystem issues
-           do_or_die("cp {0} {1} && cp {2} {3]/{4}".format(arg, target, master(arg), target, repodir)) 
+           backend.copyto(arg, target)
            if not quiet and len(args) > 1:
               announce("%s -> %s" % target)
 
@@ -753,6 +746,39 @@ dispatch = {
     "copyto":      copyto_method,
 }
 
+class RCS:
+    "Encapsulate RCS back end methods."
+    def master(self, arg):
+        return os.path.join(repodir, arg + ",v")
+    def add(self, arg):
+        "Register a file"
+        do_or_die("rcs -q -kb -i {0} </dev/null && mv {0},v {1}".format(arg, repodir))
+    def checkin(self, arg, comment):
+        "Check in a commit, with comment."
+        do_or_die("ci -l -m'{1}' {0}".format(arg, comment))
+    def checkout(self, arg, revision):
+        "Check out a revision. Leaves it writeable."
+        do_or_die("rm -f {0} && rcs -q -u {0},v && co -q -l{1} {0}".format(arg, revision))
+    def cat(self, arg, revision, fn=""):
+        "Ship the contents of a revision to stdout or a named file."
+        if fn:
+            arg += " >" + fn
+        do_or_die("co -q -p -r{1} {0}".format(arg, item.revision), loud=True)
+    def delete_tag(self, tagname, arg):
+        "Delete a specified tag."
+        do_or_die("rcs -n{0} {1}".format(tagname, arg))
+    def set_tag(self, tagname, revision, arg):
+        "Set a specified tag."
+        do_or_die("rcs -N{0}:{1} {2}".format(tagname, revision, arg))
+    def moveto(self, arg, target):
+        "Move a file and its history to a target directory."
+        # Using mv(1) evades cross-filesystem issues
+        do_or_die("mv {0} {1} && mv {2} {3]/{4}".format(arg, target, self.master(arg), target, repodir)) 
+    def copyto(self, arg, target):
+        "Copy a file and its history to a target directory."
+        # Using cp(1) evades cross-filesystem issues
+        do_or_die("cp {0} {1} && cp {2} {3]/{4}".format(arg, target, self.master(arg), target, repodir)) 
+
 if __name__ == "__main__":    
     command = list(sys.argv[1:])
     explicit = False
@@ -773,6 +799,9 @@ if __name__ == "__main__":
     if not explicit and not os.path.exists(repodir) and  os.path.exists("RCS"):
         repodir = "RCS"
 
+    # Presently there is only one backend
+    backend = RCS()
+
     if not command:
         help_method()
     else: