From 859fbf4a83f2806fdd785ca2f312d7dca8b2163e Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Tue, 14 Jul 2009 08:13:47 -0400 Subject: Updated GPLv2 to current GPLv2. Fixes Ben's bug 00f26f04-9202-4288-8744-b29abc2342d6. I also tweaked update_copyright.sh to make possible future copyright-blurb revision easier. The new algorithm is greedier, overwriting _all_ consecutive comments after a '^# Copyright' line, so do # Copyright # GPL ... GPL ... GPL # Your comment here... not # Copyright # GPL ... GPL ... GPL # # Your comment here... Without the blank line, your comment would get overwritten by the next run of update_copyright.sh. Note that catmutt is ignored by update_copyright.sh because Moritz Barsnick has only licensed his grepm code under the GPLv2 (not GPLv>=2). See the initial catmutt commit for details. --- libbe/rcs.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'libbe/rcs.py') diff --git a/libbe/rcs.py b/libbe/rcs.py index 844920a..fd87f42 100644 --- a/libbe/rcs.py +++ b/libbe/rcs.py @@ -4,19 +4,19 @@ # Chris Ball # W. Trevor King # -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. # -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. from subprocess import Popen, PIPE import codecs -- cgit From e8f8975d1d76e18ba1e8da1f095568c54c9ea6b0 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Sat, 18 Jul 2009 10:29:11 -0400 Subject: Fixed broken path in libbe.rcs.RCS._rcs_get_file_contents(binary=True). I'd forgotten to prefix the directory root, so calling be show --only-raw-body COMMIT-ID would fail if you weren't executing it in the repository root. --- libbe/rcs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libbe/rcs.py') diff --git a/libbe/rcs.py b/libbe/rcs.py index fd87f42..1024249 100644 --- a/libbe/rcs.py +++ b/libbe/rcs.py @@ -186,7 +186,7 @@ class RCS(object): if binary == False: f = codecs.open(os.path.join(self.rootdir, path), "r", self.encoding) else: - f = open(path, "rb") + f = open(os.path.join(self.rootdir, path), "rb") contents = f.read() f.close() return contents -- cgit From b3ce47285a66a35904e5e50636ce471ecb4ce29d Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Sun, 19 Jul 2009 10:48:12 -0400 Subject: Added becommands/commit.py and minor fixes. Now we can commit changes from the command line with a unified interface. The interface is much less flexible than using your particular version control system's commit command directly, so this command is mostly intended for user-interfaces and other tools that don't want to be bothered with the extra flexibility. Normalized spacing in rcs.RCS.commit to produce: summary body messages regardless of the input string format. Also fixed a "--complete" handline bug in cmdutil, and some minor docstring typos in libbe.rcs and .editor. --- libbe/rcs.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'libbe/rcs.py') diff --git a/libbe/rcs.py b/libbe/rcs.py index 1024249..7138d01 100644 --- a/libbe/rcs.py +++ b/libbe/rcs.py @@ -201,7 +201,7 @@ class RCS(object): """ Commit the current working directory, using the contents of commitfile as the comment. Return the name of the old - revision. + revision (or None if commits are not supported). """ return None def installed(self): @@ -370,8 +370,9 @@ class RCS(object): string summary and body. Return the name of the old revision (or None if versioning is not supported). """ + summary = summary.strip() if body is not None: - summary += '\n' + body + summary += '\n\n' + body.strip() + '\n' descriptor, filename = tempfile.mkstemp() revision = None try: -- cgit From a6d5f2891dc353ebe5d9d8598790a6674c174eec Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Sun, 19 Jul 2009 15:24:51 -0400 Subject: Added --allow-empty to "be commit" Previously many backends would silently add an empty commit. Not very useful. When the new --allow-empty flag and related allow_empty options are false, every versioning backend is guaranteed to raise the EmptyCommit exception in the case of an attempted empty commit. --- libbe/rcs.py | 48 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-) (limited to 'libbe/rcs.py') diff --git a/libbe/rcs.py b/libbe/rcs.py index 7138d01..3bf8c9d 100644 --- a/libbe/rcs.py +++ b/libbe/rcs.py @@ -61,10 +61,13 @@ def installed_rcs(): class CommandError(Exception): - def __init__(self, err_str, status): - Exception.__init__(self, "Command failed (%d): %s" % (status, err_str)) - self.err_str = err_str + def __init__(self, command, status, err_str): + strerror = ["Command failed (%d):\n %s\n" % (status, err_str), + "while executing\n %s" % command] + Exception.__init__(self, "\n".join(strerror)) + self.command = command self.status = status + self.err_str = err_str class SettingIDnotSupported(NotImplementedError): pass @@ -86,6 +89,10 @@ class NoSuchFile(Exception): path = os.path.abspath(os.path.join(root, pathname)) Exception.__init__(self, "No such file: %s" % path) +class EmptyCommit(Exception): + def __init__(self): + Exception.__init__(self, "No changes to commit") + def new(): return RCS() @@ -197,11 +204,14 @@ class RCS(object): dir specifies a directory to create the duplicate in. """ shutil.copytree(self.rootdir, directory, True) - def _rcs_commit(self, commitfile): + def _rcs_commit(self, commitfile, allow_empty=False): """ Commit the current working directory, using the contents of commitfile as the comment. Return the name of the old revision (or None if commits are not supported). + + If allow_empty == False, raise EmptyCommit if there are no + changes to commit. """ return None def installed(self): @@ -364,22 +374,25 @@ class RCS(object): shutil.rmtree(self._duplicateBasedir) self._duplicateBasedir = None self._duplicateDirname = None - def commit(self, summary, body=None): + def commit(self, summary, body=None, allow_empty=False): """ Commit the current working directory, with a commit message string summary and body. Return the name of the old revision (or None if versioning is not supported). + + If allow_empty == False (the default), raise EmptyCommit if + there are no changes to commit. """ - summary = summary.strip() + summary = summary.strip()+'\n' if body is not None: - summary += '\n\n' + body.strip() + '\n' + summary += '\n' + body.strip() + '\n' descriptor, filename = tempfile.mkstemp() revision = None try: temp_file = os.fdopen(descriptor, 'wb') temp_file.write(summary) temp_file.flush() - revision = self._rcs_commit(filename) + revision = self._rcs_commit(filename, allow_empty=allow_empty) temp_file.close() finally: os.remove(filename) @@ -388,7 +401,20 @@ class RCS(object): pass def postcommit(self, directory): pass + def _u_any_in_string(self, list, string): + """ + Return True if any of the strings in list are in string. + Otherwise return False. + """ + for list_string in list: + if list_string in string: + return True + return False def _u_invoke(self, args, stdin=None, expect=(0,), cwd=None): + """ + expect should be a tuple of allowed exit codes. cwd should be + the directory from which the command will be executed. + """ if cwd == None: cwd = self.rootdir if self.verboseInvoke == True: @@ -401,15 +427,13 @@ class RCS(object): q = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True, cwd=cwd) except OSError, e : - strerror = "%s\nwhile executing %s" % (e.args[1], args) - raise CommandError(strerror, e.args[0]) + raise CommandError(args, e.args[0], e) output, error = q.communicate(input=stdin) status = q.wait() if self.verboseInvoke == True: print >> sys.stderr, "%d\n%s%s" % (status, output, error) if status not in expect: - strerror = "%s\nwhile executing %s\n%s" % (args[1], args, error) - raise CommandError(strerror, status) + raise CommandError(args, status, error) return status, output, error def _u_invoke_client(self, *args, **kwargs): directory = kwargs.get('directory',None) -- cgit From 4c7a9d837a268480e61124bba84b5fb01ec3728f Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Tue, 21 Jul 2009 07:28:26 -0400 Subject: Cleaned up saving/sync_with_disk. Got rid of a whole bunch of redundant .save() calls when sync_with_disk==True. Fixed up the "File-system access" portion of the BugDir docstring so we can all remember how things are supposed to work ;). Note that some .save() calls are still required. For example in becommands/merge.py, the copied comments have their .bug changed, but that is not a versioned property, so it doesn't trigger an automatic save, and we have to force the .save() by hand. libbe.rcs.RCS.mkdir() is now recursive by default, but you can set check_parents==False if you want it to fail in the case of missing parents. Because of the recursion, we removed the .update() call on preexisting directories, since there will be at least one of these occurrences for every .mkdir(check_parents=True) call, and I don't know of any VCS that actually needs them... Also stripped trailing whitespace from some files... --- libbe/rcs.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'libbe/rcs.py') diff --git a/libbe/rcs.py b/libbe/rcs.py index 3bf8c9d..1e1cfa7 100644 --- a/libbe/rcs.py +++ b/libbe/rcs.py @@ -339,11 +339,15 @@ class RCS(object): self.add(path) else: self.update(path) - def mkdir(self, path, allow_no_rcs=False): + def mkdir(self, path, allow_no_rcs=False, check_parents=True): """ Create (if neccessary) a directory at path under version control. """ + if check_parents == True: + parent = os.path.dirname(path) + if not os.path.exists(parent): # recurse through parents + self.mkdir(parent, allow_no_rcs, check_parents) if not os.path.exists(path): os.mkdir(path) if self._use_rcs(path, allow_no_rcs): @@ -351,7 +355,9 @@ class RCS(object): else: assert os.path.isdir(path) if self._use_rcs(path, allow_no_rcs): - self.update(path) + #self.update(path)# Don't update directories. Changing files + pass # underneath them should be sufficient. + def duplicate_repo(self, revision=None): """ Get the repository as it was in a given revision. -- cgit From caf0111d9c571ac268c235880e6d18fa512e9efa Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Thu, 23 Jul 2009 11:43:04 -0400 Subject: libbe.rcs.RCS.commit() now actually calls .pre/postcommit(). It hadn't before, which defeats the Pu purpose of hook functions. This hand't caused any problems though, since only libbe.bzr defined a postcommit() and there were no precommit() definitions. Bzr's postcommit() had been to auto-merge from the default merge source. Yikes! Removed that ;). --- libbe/rcs.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'libbe/rcs.py') diff --git a/libbe/rcs.py b/libbe/rcs.py index 1e1cfa7..294b8e0 100644 --- a/libbe/rcs.py +++ b/libbe/rcs.py @@ -398,14 +398,22 @@ class RCS(object): temp_file = os.fdopen(descriptor, 'wb') temp_file.write(summary) temp_file.flush() + self.precommit() revision = self._rcs_commit(filename, allow_empty=allow_empty) temp_file.close() + self.postcommit() finally: os.remove(filename) return revision - def precommit(self, directory): + def precommit(self): + """ + Executed before all attempted commits. + """ pass - def postcommit(self, directory): + def postcommit(self): + """ + Only executed after successful commits. + """ pass def _u_any_in_string(self, list, string): """ -- cgit