diff options
Diffstat (limited to 'libbe')
-rw-r--r-- | libbe/bugdir.py | 7 | ||||
-rw-r--r-- | libbe/bzr.py | 9 | ||||
-rw-r--r-- | libbe/hg.py | 115 | ||||
-rw-r--r-- | libbe/names.py | 12 | ||||
-rw-r--r-- | libbe/rcs.py | 20 |
5 files changed, 147 insertions, 16 deletions
diff --git a/libbe/bugdir.py b/libbe/bugdir.py index 414b47e..bfe9a27 100644 --- a/libbe/bugdir.py +++ b/libbe/bugdir.py @@ -141,7 +141,7 @@ class BugDir: except NoSuchFile: self.settings = {"rcs_name": "None"} - rcs_name = setting_property("rcs_name", ("None", "bzr", "Arch")) + rcs_name = setting_property("rcs_name", ("None", "bzr", "Arch", "hg")) _rcs = None target = setting_property("target") @@ -287,8 +287,11 @@ class Bug(object): return Comment(uuid, self) def iter_comment_ids(self): + path = self.get_path("comments") + if not os.path.isdir(path): + return try: - for uuid in os.listdir(self.get_path("comments")): + for uuid in os.listdir(path): if (uuid.startswith('.')): continue yield uuid diff --git a/libbe/bzr.py b/libbe/bzr.py index b53429c..ddda334 100644 --- a/libbe/bzr.py +++ b/libbe/bzr.py @@ -25,14 +25,7 @@ def invoke_client(*args, **kwargs): expect = kwargs.get('expect', (0, 1)) cl_args = ["bzr"] cl_args.extend(args) - if directory: - old_dir = os.getcwd() - os.chdir(directory) - try: - status,output,error = invoke(cl_args, expect) - finally: - if directory: - os.chdir(old_dir) + status,output,error = invoke(cl_args, expect, cwd=directory) return status, output def add_id(filename, paranoid=False): diff --git a/libbe/hg.py b/libbe/hg.py new file mode 100644 index 0000000..35de8e0 --- /dev/null +++ b/libbe/hg.py @@ -0,0 +1,115 @@ +# Copyright (C) 2007 Steve Borho <steve@borho.org> +# +# 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. +# +# 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 +import os +import tempfile + +import config +from rcs import invoke, CommandError + +def invoke_client(*args, **kwargs): + directory = kwargs['directory'] + expect = kwargs.get('expect', (0, 1)) + cl_args = ["hg"] + cl_args.extend(args) + status,output,error = invoke(cl_args, expect, cwd=directory) + return status, output + +def add_id(filename, paranoid=False): + invoke_client("add", filename, directory='.') + +def delete_id(filename): + invoke_client("rm", filename, directory='.') + +def mkdir(path, paranoid=False): + os.mkdir(path) + +def set_file_contents(path, contents): + add = not os.path.exists(path) + file(path, "wb").write(contents) + if add: + add_id(path) + +def lookup_revision(revno, directory): + return invoke_client('log', '--rev', str(revno), '--template={node}', + directory=directory)[1].rstrip('\n') + +def export(revno, directory, revision_dir): + invoke_client("archive", "--rev", str(revno), revision_dir, + directory=directory) + +def find_or_make_export(revno, directory): + revision_id = lookup_revision(revno, directory) + home = os.path.expanduser("~") + revision_root = os.path.join(home, ".be_revs") + if not os.path.exists(revision_root): + os.mkdir(revision_root) + revision_dir = os.path.join(revision_root, revision_id) + if not os.path.exists(revision_dir): + export(revno, directory, revision_dir) + return revision_dir + +def hg_root(path): + return invoke_client("root", "-R", path, directory=None)[1].rstrip('\r') + +def path_in_reference(bug_dir, spec): + if spec is None: + spec = int(invoke_client('tip', '--template="{rev}"', + directory=bug_dir)[1]) + rel_bug_dir = bug_dir[len(hg_root(bug_dir)):] + export_root = find_or_make_export(spec, directory=bug_dir) + return os.path.join(export_root, rel_bug_dir) + + +def unlink(path): + try: + os.unlink(path) + delete_id(path) + except OSError, e: + if e.errno != 2: + raise + + +def detect(path): + """Detect whether a directory is revision-controlled using Mercurial""" + path = os.path.realpath(path) + old_path = None + while True: + if os.path.exists(os.path.join(path, ".hg")): + return True + if path == old_path: + return False + old_path = path + path = os.path.dirname(path) + +def precommit(directory): + pass + +def commit(directory, summary, body=None): + if body is not None: + summary += '\n' + body + descriptor, filename = tempfile.mkstemp() + try: + temp_file = os.fdopen(descriptor, 'wb') + temp_file.write(summary) + temp_file.close() + invoke_client('commit', '--logfile', filename, directory=directory) + finally: + os.unlink(filename) + +def postcommit(directory): + pass + +name = "hg" diff --git a/libbe/names.py b/libbe/names.py index cbcfbf8..d2e077a 100644 --- a/libbe/names.py +++ b/libbe/names.py @@ -14,13 +14,21 @@ # 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 -import commands + import os import sys def uuid(): - return commands.getoutput('uuidgen') + # this code borrowed from standard commands module + # but adapted to win32 + pipe = os.popen('uuidgen', 'r') + text = pipe.read() + sts = pipe.close() + if sts not in (0, None): + raise "Failed to run uuidgen" + if text[-1:] == '\n': text = text[:-1] + return text def creator(): if sys.platform != "win32": diff --git a/libbe/rcs.py b/libbe/rcs.py index ac96734..64503db 100644 --- a/libbe/rcs.py +++ b/libbe/rcs.py @@ -15,6 +15,8 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from subprocess import Popen, PIPE +import sys + def rcs_by_name(rcs_name): """Return the module for the RCS with the given name""" if rcs_name == "Arch": @@ -23,6 +25,9 @@ def rcs_by_name(rcs_name): elif rcs_name == "bzr": import bzr return bzr + elif rcs_name == "hg": + import hg + return hg elif rcs_name == "None": import no_rcs return no_rcs @@ -31,10 +36,13 @@ def detect(dir): """Return the module for the rcs being used in this directory""" import arch import bzr + import hg if arch.detect(dir): return arch elif bzr.detect(dir): return bzr + elif hg.detect(dir): + return hg import no_rcs return no_rcs @@ -44,10 +52,14 @@ class CommandError(Exception): self.err_str = err_str self.status = status -def invoke(args, expect=(0,)): - q = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE) - output = q.stdout.read() - error = q.stderr.read() +def invoke(args, expect=(0,), cwd=None): + if sys.platform != "win32": + q = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE, cwd=cwd) + else: + # win32 don't have os.execvp() so have to run command in a shell + q = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True, + cwd=cwd) + output, error = q.communicate() status = q.wait() if status not in expect: raise CommandError(error, status) |