]> thyrsus.com Git - src.git/commitdiff
Added -e option. Regression test passes.
authorEric S. Raymond <esr@thyrsus.com>
Mon, 10 Nov 2014 15:36:46 +0000 (10:36 -0500)
committerEric S. Raymond <esr@thyrsus.com>
Mon, 10 Nov 2014 15:36:46 +0000 (10:36 -0500)
NEWS
src
src.asc

diff --git a/NEWS b/NEWS
index e6f82a974bc22214f45317b143ae1c96b634e586..4bf7238d80537d1204539cdd28681cdcafafc8ca 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,7 @@
 `                      src project news
 Repository head:
    Improvements to src fast-import.
+   src commit now has an -e option to force editing after -m or -f.
 
 0.3: 2014-11-09
    There is now a "src status" command, and .srcignore affects it.
diff --git a/src b/src
index 1e57c919871cde31c9a3aad651ffa366c7350643..8cb5ca743012bf036083f862cb9d0985fba884b5 100755 (executable)
--- a/src
+++ b/src
@@ -198,11 +198,11 @@ src add ['file'...]
    Initialize new project histories for specified files. Creates
    the repository directory if required.
 
-src commit [- | -m 'commentstring' | -f 'commentfile'] ['file'...]
+src commit [- | -m 'commentstring' | -f 'commentfile' | -e] ['file'...]
    Enters a commit for specified files. Separately to each one.
    With '-', take comment text from stdin; with '-m' use the
    following string as the comment; with '-f' take from a file.
-   ci is a synonym for commit.
+   With '-e', edit even after '-f' or '-m'.   ci is a synonym for commit.
 
 src checkout ['revision'] ['file'...]
    Refresh the working copy of the file(s) from their history files.
@@ -374,56 +374,59 @@ def add_method(*args):
            if not quiet and len(ctx.args) > 1:
               announce("%s -> 0" % arg) 
 
-def get_comment(legend, args):
-    "Attempt to collect a comment from command line args."
-    comment = None
-    if args:
-        if args[0] == '--':
-            args.pop(0)
-        elif args[0] == "-":
-            comment = sys.stdin.read()
-            args.pop(0)
-        elif args[0] == "-m":
-            args.pop(0)
-            try:
-                comment = args[0]
+class CommentContext:
+    def __init__(self, legend, args):
+        "Attempt to collect a comment from command line args."
+        self.comment = None
+        self.force_edit = False
+        if args:
+            if args[0] == '--':
                 args.pop(0)
-            except IndexError:
-                croak("%s -m requires a following string" % legend)
-        elif args[0] == "-f":
-            args.pop(0)
-            try:
-                comment = open(args[0]).read()
+            elif args[0] == "-":
+                self.comment = sys.stdin.read()
                 args.pop(0)
-            except IndexError:
-                croak("%s -f requires a following filename argument" % legend)
-            except OSError:
-                croak("couldn't open %s." % args[1])
-    return comment
-
-def edit_comment():
-    "Interactively edit a coment."
-    editor = os.getenv("EDITOR") or "emacsclient"
-    commentfile = "/tmp/src%dtmp" % os.getpid()
-    do_or_die(editor + " " + commentfile, loud=True)
-    return open(commentfile).read()
-
-def prepare_comment(comment, metadata):
-    "Validate comment text and preapare it to be passed to the back end."
-    # Delimiter won't be set just after add
-    if metadata.delimiter and metadata.delimiter in comment:
-        croak("malformed comment")
-    if not comment.endswith("\n"):
-        comment += "\n"
-    # Because it's going to be handed back in single quotes
-    return comment.replace("'", r"\'")
+            elif args[0] == "-e":
+                self.force_edit = True
+            elif args[0] == "-m":
+                args.pop(0)
+                try:
+                    self.comment = args[0]
+                    args.pop(0)
+                except IndexError:
+                    croak("%s -m requires a following string" % legend)
+            elif args[0] == "-f":
+                args.pop(0)
+                try:
+                    self.comment = open(args[0]).read()
+                    args.pop(0)
+                except IndexError:
+                    croak("%s -f requires a following filename argument" % legend)
+                except OSError:
+                    croak("couldn't open %s." % args[1])
+    def edit(self, metadata):
+        "Interactively edit a comment if required, then prepare for handoff."
+        if self.comment is None or self.force_edit:
+            editor = os.getenv("EDITOR") or "emacsclient"
+            commentfile = "/tmp/src%dtmp" % os.getpid()
+            do_or_die(editor + " " + commentfile, loud=True)
+            self.comment = open(commentfile).read()
+        # Delimiter won't be set just after add
+        if metadata.delimiter and metadata.delimiter in self.comment:
+            croak("malformed comment")
+        if not self.comment.endswith("\n"):
+            self.comment += "\n"
+        # Because it's going to be handed back as a shell argument
+        self.comment = "'" + self.comment.replace("'", r"\'") + "'"
+    def content(self):
+        "Reurn the edited comment."
+        return self.comment
 
 def commit_method(*args):
     "Commit changes to files."
     if not os.path.exists(repodir):
         croak("repository subdirectory %s does not exist" % repodir)
     args = list(args)
-    comment = get_comment("commit", args)
+    comment = CommentContext("commit", args)
     ctx = CommandContext("commit", args, require_empty=True)
     for arg in ctx.args:
        if not os.path.exists(arg):
@@ -432,11 +435,9 @@ def commit_method(*args):
            croak("%s is not registered." % arg)
        else:
            metadata = History(arg)
-           if not comment:
-               comment = edit_comment()
-           comment = prepare_comment(comment, metadata)
+           comment.edit(metadata)    
            with backend.lifter(arg):
-               backend.checkin(arg, comment)
+               backend.checkin(arg, comment.content())
            if not quiet and len(args) > 1:
                announce("%s -> %d" % (arg, len(metadata))) 
 
@@ -445,7 +446,7 @@ def amend_method(*args):
     if not os.path.exists(repodir):
         croak("repository subdirectory %s does not exist" % repodir)
     args = list(args)
-    comment = get_comment("amend", args)
+    comment = CommentContext("amend", args)
     ctx = CommandContext("amend", args)
     if ctx.is_range():
         croak("amend cannot take a range")
@@ -459,11 +460,11 @@ def amend_method(*args):
            ctx.resolve(metadata)
            if ctx.is_empty():
                ctx.start = metadata.tip().revno
-           if not comment:
-               comment = edit_comment()
-           comment = prepare_comment(comment, metadata)
+           comment.edit(metadata)
            with backend.lifter(arg):
-               backend.amend(arg, metadata.revno_to_rcs(ctx.start), comment)
+               backend.amend(arg,
+                             metadata.revno_to_rcs(ctx.start),
+                             comment.content())
            if not quiet and len(args) > 1:
                announce("%s : %d" % (arg, len(metadata))) 
 
@@ -886,7 +887,8 @@ class RCS:
         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))
+        # Relies on caller to escape comment string
+        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))
diff --git a/src.asc b/src.asc
index e6f1263544e3b7f28b8fc7a0b6efd7679d0f51a2..e61e8b90f39fbbbe8b4dfbd0489a94fceb012cd8 100644 (file)
--- a/src.asc
+++ b/src.asc
@@ -48,11 +48,11 @@ src add ['file'...]::
    Initialize new project histories for specified files. Creates
    the repository directory if required.
 
-src commit [- | -m commentstring | -f commentfile] ['file'...]::
+src commit [- | -m commentstring | -f commentfile | -e] ['file'...]::
    Enters a commit for specified files. Separately to each one.
    With '-', take comment text from stdin; with '-m' use the
-   following string as the comment;with '-f' take from a file.
-   ci is a synonym for commit.
+   following string as the comment; with '-f' take from a file.
+   With '-e', edit even after '-f' or '-m'. ci is a synonym for commit.
 
 src checkout [revision] ['file'...]::
    Refresh the working copy of the file(s) from their history files.