From 49a7771336ce09f6d42c7699ef32aecea0e83182 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Mon, 7 Dec 2009 20:07:55 -0500 Subject: Initial directory restructuring to clarify dependencies --- libbe/storage/vcs/darcs.py | 192 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 libbe/storage/vcs/darcs.py (limited to 'libbe/storage/vcs/darcs.py') diff --git a/libbe/storage/vcs/darcs.py b/libbe/storage/vcs/darcs.py new file mode 100644 index 0000000..d94eaef --- /dev/null +++ b/libbe/storage/vcs/darcs.py @@ -0,0 +1,192 @@ +# Copyright (C) 2009 Gianluca Montecchi +# 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 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., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +""" +Darcs backend. +""" + +import codecs +import os +import re +import sys +try: # import core module, Python >= 2.5 + from xml.etree import ElementTree +except ImportError: # look for non-core module + from elementtree import ElementTree +from xml.sax.saxutils import unescape + +import libbe +import vcs +if libbe.TESTING == True: + import doctest + import unittest + + +def new(): + return Darcs() + +class Darcs(vcs.VCS): + name="darcs" + client="darcs" + versioned=True + def _vcs_version(self): + status,output,error = self._u_invoke_client("--version") + num_part = output.split(" ")[0] + self.parsed_version = [int(i) for i in num_part.split(".")] + return output + def _vcs_detect(self, path): + if self._u_search_parent_directories(path, "_darcs") != None : + return True + return False + def _vcs_root(self, path): + """Find the root of the deepest repository containing path.""" + # Assume that nothing funny is going on; in particular, that we aren't + # dealing with a bare repo. + if os.path.isdir(path) != True: + path = os.path.dirname(path) + darcs_dir = self._u_search_parent_directories(path, "_darcs") + if darcs_dir == None: + return None + return os.path.dirname(darcs_dir) + def _vcs_init(self, path): + self._u_invoke_client("init", cwd=path) + def _vcs_get_user_id(self): + # following http://darcs.net/manual/node4.html#SECTION00410030000000000000 + # as of June 29th, 2009 + if self.rootdir == None: + return None + darcs_dir = os.path.join(self.rootdir, "_darcs") + if darcs_dir != None: + for pref_file in ["author", "email"]: + pref_path = os.path.join(darcs_dir, "prefs", pref_file) + if os.path.exists(pref_path): + return self.get_file_contents(pref_path) + for env_variable in ["DARCS_EMAIL", "EMAIL"]: + if env_variable in os.environ: + return os.environ[env_variable] + return None + def _vcs_set_user_id(self, value): + if self.rootdir == None: + self.root(".") + if self.rootdir == None: + raise vcs.SettingIDnotSupported + author_path = os.path.join(self.rootdir, "_darcs", "prefs", "author") + f = codecs.open(author_path, "w", self.encoding) + f.write(value) + f.close() + def _vcs_add(self, path): + if os.path.isdir(path): + return + self._u_invoke_client("add", path) + def _vcs_remove(self, path): + if not os.path.isdir(self._u_abspath(path)): + os.remove(os.path.join(self.rootdir, path)) # darcs notices removal + def _vcs_update(self, path): + pass # darcs notices changes + def _vcs_get_file_contents(self, path, revision=None, binary=False): + if revision == None: + return vcs.VCS._vcs_get_file_contents(self, path, revision, + binary=binary) + else: + if self.parsed_version[0] >= 2: + status,output,error = self._u_invoke_client( \ + "show", "contents", "--patch", revision, path) + return output + else: + # Darcs versions < 2.0.0pre2 lack the "show contents" command + + status,output,error = self._u_invoke_client( \ + "diff", "--unified", "--from-patch", revision, path, + unicode_output=False) + major_patch = output + status,output,error = self._u_invoke_client( \ + "diff", "--unified", "--patch", revision, path, + unicode_output=False) + target_patch = output + + # "--output -" to be supported in GNU patch > 2.5.9 + # but that hasn't been released as of June 30th, 2009. + + # Rewrite path to status before the patch we want + args=["patch", "--reverse", path] + status,output,error = self._u_invoke(args, stdin=major_patch) + # Now apply the patch we want + args=["patch", path] + status,output,error = self._u_invoke(args, stdin=target_patch) + + if os.path.exists(os.path.join(self.rootdir, path)) == True: + contents = vcs.VCS._vcs_get_file_contents(self, path, + binary=binary) + else: + contents = "" + + # Now restore path to it's current incarnation + args=["patch", "--reverse", path] + status,output,error = self._u_invoke(args, stdin=target_patch) + args=["patch", path] + status,output,error = self._u_invoke(args, stdin=major_patch) + current_contents = vcs.VCS._vcs_get_file_contents(self, path, + binary=binary) + return contents + def _vcs_duplicate_repo(self, directory, revision=None): + if revision==None: + vcs.VCS._vcs_duplicate_repo(self, directory, revision) + else: + self._u_invoke_client("put", "--to-patch", revision, directory) + def _vcs_commit(self, commitfile, allow_empty=False): + id = self.get_user_id() + if '@' not in id: + id = "%s <%s@invalid.com>" % (id, id) + args = ['record', '--all', '--author', id, '--logfile', commitfile] + status,output,error = self._u_invoke_client(*args) + empty_strings = ["No changes!"] + if self._u_any_in_string(empty_strings, output) == True: + if allow_empty == False: + raise vcs.EmptyCommit() + # note that darcs does _not_ make an empty revision. + # this returns the last non-empty revision id... + revision = self._vcs_revision_id(-1) + else: + revline = re.compile("Finished recording patch '(.*)'") + match = revline.search(output) + assert match != None, output+error + assert len(match.groups()) == 1 + revision = match.groups()[0] + return revision + def _vcs_revision_id(self, index): + status,output,error = self._u_invoke_client("changes", "--xml") + revisions = [] + xml_str = output.encode("unicode_escape").replace(r"\n", "\n") + element = ElementTree.XML(xml_str) + assert element.tag == "changelog", element.tag + for patch in element.getchildren(): + assert patch.tag == "patch", patch.tag + for child in patch.getchildren(): + if child.tag == "name": + text = unescape(unicode(child.text).decode("unicode_escape").strip()) + revisions.append(text) + revisions.reverse() + try: + return revisions[index] + except IndexError: + return None + +if libbe.TESTING == True: + vcs.make_vcs_testcase_subclasses(Darcs, sys.modules[__name__]) + + unitsuite =unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + suite = unittest.TestSuite([unitsuite, doctest.DocTestSuite()]) -- cgit From e3a48b356ace6bd88f064fb65f16c53dfdc5f8eb Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Sun, 13 Dec 2009 21:56:34 -0500 Subject: Move Darcs over to Storage format. We have to work around the same issue as mercurial (hg) issue 618. I can't find a Darcs bug report for this, but it's been fixed somewhere between 1.0.9 and 2.3.1. Example scripts demonstrating the bug: $ darcs=/usr/bin/darcs $ mkdir x; cd x; $darcs init; echo a > b; $darcs add b; \ $darcs record --all --author 'x ' --logfile b; \ echo z>b; $darcs record --all --author 'x ' --logfile b; \ echo g>b; $darcs record --all --author 'x ' --logfile b; \ cd ..; rm -rf x > /dev/null; $darcs --version Finished recording patch 'a' No changes! No changes! 1.0.9 (release) And showing it's been fixed: $ darcs=~/.cabal/bin/darcs $ mkdir x; cd x; $darcs init; echo a > b; $darcs add b; \ $darcs record --all --author 'x ' --logfile b; \ echo z>b; $darcs record --all --author 'x ' --logfile b; \ echo g>b; $darcs record --all --author 'x ' --logfile b; \ cd ..; rm -rf x > /dev/null; $darcs --version Finished recording patch 'a' Finished recording patch 'z' Finished recording patch 'g' 2.3.1 (release) --- libbe/storage/vcs/darcs.py | 164 +++++++++++++++++++++++++-------------------- 1 file changed, 93 insertions(+), 71 deletions(-) (limited to 'libbe/storage/vcs/darcs.py') diff --git a/libbe/storage/vcs/darcs.py b/libbe/storage/vcs/darcs.py index d94eaef..97e31ff 100644 --- a/libbe/storage/vcs/darcs.py +++ b/libbe/storage/vcs/darcs.py @@ -22,7 +22,9 @@ Darcs backend. import codecs import os import re +import shutil import sys +import time # work around http://mercurial.selenic.com/bts/issue618 try: # import core module, Python >= 2.5 from xml.etree import ElementTree except ImportError: # look for non-core module @@ -30,7 +32,8 @@ except ImportError: # look for non-core module from xml.sax.saxutils import unescape import libbe -import vcs +import base + if libbe.TESTING == True: import doctest import unittest @@ -39,124 +42,136 @@ if libbe.TESTING == True: def new(): return Darcs() -class Darcs(vcs.VCS): - name="darcs" - client="darcs" - versioned=True +class Darcs(base.VCS): + name='darcs' + client='darcs' + + def __init__(self, *args, **kwargs): + base.VCS.__init__(self, *args, **kwargs) + self.versioned = True + self.__updated = [] # work around http://mercurial.selenic.com/bts/issue618 + def _vcs_version(self): - status,output,error = self._u_invoke_client("--version") - num_part = output.split(" ")[0] - self.parsed_version = [int(i) for i in num_part.split(".")] + status,output,error = self._u_invoke_client('--version') + num_part = output.split(' ')[0] + self.parsed_version = [int(i) for i in num_part.split('.')] return output + + def _vcs_get_user_id(self): + # following http://darcs.net/manual/node4.html#SECTION00410030000000000000 + # as of June 29th, 2009 + if self.repo == None: + return None + darcs_dir = os.path.join(self.repo, '_darcs') + if darcs_dir != None: + for pref_file in ['author', 'email']: + pref_path = os.path.join(darcs_dir, 'prefs', pref_file) + if os.path.exists(pref_path): + return self.get_file_contents(pref_path) + for env_variable in ['DARCS_EMAIL', 'EMAIL']: + if env_variable in os.environ: + return os.environ[env_variable] + return None + def _vcs_detect(self, path): if self._u_search_parent_directories(path, "_darcs") != None : return True return False + def _vcs_root(self, path): """Find the root of the deepest repository containing path.""" # Assume that nothing funny is going on; in particular, that we aren't # dealing with a bare repo. if os.path.isdir(path) != True: path = os.path.dirname(path) - darcs_dir = self._u_search_parent_directories(path, "_darcs") + darcs_dir = self._u_search_parent_directories(path, '_darcs') if darcs_dir == None: return None return os.path.dirname(darcs_dir) + def _vcs_init(self, path): - self._u_invoke_client("init", cwd=path) - def _vcs_get_user_id(self): - # following http://darcs.net/manual/node4.html#SECTION00410030000000000000 - # as of June 29th, 2009 - if self.rootdir == None: - return None - darcs_dir = os.path.join(self.rootdir, "_darcs") - if darcs_dir != None: - for pref_file in ["author", "email"]: - pref_path = os.path.join(darcs_dir, "prefs", pref_file) - if os.path.exists(pref_path): - return self.get_file_contents(pref_path) - for env_variable in ["DARCS_EMAIL", "EMAIL"]: - if env_variable in os.environ: - return os.environ[env_variable] - return None - def _vcs_set_user_id(self, value): - if self.rootdir == None: - self.root(".") - if self.rootdir == None: - raise vcs.SettingIDnotSupported - author_path = os.path.join(self.rootdir, "_darcs", "prefs", "author") - f = codecs.open(author_path, "w", self.encoding) - f.write(value) - f.close() + self._u_invoke_client('init', cwd=path) + + def _vcs_destroy(self): + vcs_dir = os.path.join(self.repo, '_darcs') + if os.path.exists(vcs_dir): + shutil.rmtree(vcs_dir) + def _vcs_add(self, path): if os.path.isdir(path): return - self._u_invoke_client("add", path) + self._u_invoke_client('add', path) + def _vcs_remove(self, path): if not os.path.isdir(self._u_abspath(path)): - os.remove(os.path.join(self.rootdir, path)) # darcs notices removal + os.remove(os.path.join(self.repo, path)) # darcs notices removal + def _vcs_update(self, path): + self.__updated.append(path) # work around http://mercurial.selenic.com/bts/issue618 pass # darcs notices changes - def _vcs_get_file_contents(self, path, revision=None, binary=False): + + def _vcs_get_file_contents(self, path, revision=None): if revision == None: - return vcs.VCS._vcs_get_file_contents(self, path, revision, - binary=binary) + return base.VCS._vcs_get_file_contents(self, path, revision) else: if self.parsed_version[0] >= 2: status,output,error = self._u_invoke_client( \ - "show", "contents", "--patch", revision, path) + 'show', 'contents', '--patch', revision, path) return output else: - # Darcs versions < 2.0.0pre2 lack the "show contents" command + # Darcs versions < 2.0.0pre2 lack the 'show contents' command status,output,error = self._u_invoke_client( \ - "diff", "--unified", "--from-patch", revision, path, + 'diff', '--unified', '--from-patch', revision, path, unicode_output=False) major_patch = output status,output,error = self._u_invoke_client( \ - "diff", "--unified", "--patch", revision, path, + 'diff', '--unified', '--patch', revision, path, unicode_output=False) target_patch = output - # "--output -" to be supported in GNU patch > 2.5.9 + # '--output -' to be supported in GNU patch > 2.5.9 # but that hasn't been released as of June 30th, 2009. # Rewrite path to status before the patch we want - args=["patch", "--reverse", path] + args=['patch', '--reverse', path] status,output,error = self._u_invoke(args, stdin=major_patch) # Now apply the patch we want - args=["patch", path] + args=['patch', path] status,output,error = self._u_invoke(args, stdin=target_patch) - if os.path.exists(os.path.join(self.rootdir, path)) == True: - contents = vcs.VCS._vcs_get_file_contents(self, path, - binary=binary) + if os.path.exists(os.path.join(self.repo, path)) == True: + contents = base.VCS._vcs_get_file_contents(self, path) else: - contents = "" + contents = '' # Now restore path to it's current incarnation - args=["patch", "--reverse", path] + args=['patch', '--reverse', path] status,output,error = self._u_invoke(args, stdin=target_patch) - args=["patch", path] + args=['patch', path] status,output,error = self._u_invoke(args, stdin=major_patch) - current_contents = vcs.VCS._vcs_get_file_contents(self, path, - binary=binary) + current_contents = base.VCS._vcs_get_file_contents(self, path) return contents - def _vcs_duplicate_repo(self, directory, revision=None): - if revision==None: - vcs.VCS._vcs_duplicate_repo(self, directory, revision) - else: - self._u_invoke_client("put", "--to-patch", revision, directory) + def _vcs_commit(self, commitfile, allow_empty=False): id = self.get_user_id() - if '@' not in id: - id = "%s <%s@invalid.com>" % (id, id) + if id == None or '@' not in id: + id = '%s <%s@invalid.com>' % (id, id) args = ['record', '--all', '--author', id, '--logfile', commitfile] status,output,error = self._u_invoke_client(*args) - empty_strings = ["No changes!"] + empty_strings = ['No changes!'] + # work around http://mercurial.selenic.com/bts/issue618 + if self._u_any_in_string(empty_strings, output) == True \ + and len(self.__updated) > 0: + time.sleep(1) + for path in self.__updated: + os.utime(os.path.join(self.repo, path), None) + status,output,error = self._u_invoke_client(*args) + self.__updated = [] + # end work around if self._u_any_in_string(empty_strings, output) == True: if allow_empty == False: - raise vcs.EmptyCommit() + raise base.EmptyCommit() # note that darcs does _not_ make an empty revision. # this returns the last non-empty revision id... revision = self._vcs_revision_id(-1) @@ -167,26 +182,33 @@ class Darcs(vcs.VCS): assert len(match.groups()) == 1 revision = match.groups()[0] return revision + def _vcs_revision_id(self, index): - status,output,error = self._u_invoke_client("changes", "--xml") + status,output,error = self._u_invoke_client('changes', '--xml') revisions = [] - xml_str = output.encode("unicode_escape").replace(r"\n", "\n") + xml_str = output.encode('unicode_escape').replace(r'\n', '\n') element = ElementTree.XML(xml_str) - assert element.tag == "changelog", element.tag + assert element.tag == 'changelog', element.tag for patch in element.getchildren(): - assert patch.tag == "patch", patch.tag + assert patch.tag == 'patch', patch.tag for child in patch.getchildren(): - if child.tag == "name": - text = unescape(unicode(child.text).decode("unicode_escape").strip()) + if child.tag == 'name': + text = unescape(unicode(child.text).decode('unicode_escape').strip()) revisions.append(text) revisions.reverse() try: - return revisions[index] + if index > 0: + return revisions[index-1] + elif index < 0: + return revisions[index] + else: + return None except IndexError: return None + if libbe.TESTING == True: - vcs.make_vcs_testcase_subclasses(Darcs, sys.modules[__name__]) + base.make_vcs_testcase_subclasses(Darcs, sys.modules[__name__]) unitsuite =unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) suite = unittest.TestSuite([unitsuite, doctest.DocTestSuite()]) -- cgit From 89b7a1411e4658e831f5d635534b24355dbb941d Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Tue, 15 Dec 2009 06:44:20 -0500 Subject: Fixed libbe.command.diff + ugly BugDir.duplicate_bugdir implementation duplicate_bugdir() works, but for the vcs backends, it could require shelling out for _every_ file read. This could, and probably will, be horribly slow. Still it works ;). I'm not sure what a better implementation would be. The old implementation checked out the entire earlier state into a temporary directory pros: single shell out, simple upgrade implementation cons: wouldn't work well for HTTP backens I think a good solution would run along the lines of the currently commented out code in duplicate_bugdir(), where a VersionedStorage.changed_since(revision) call would give you a list of changed files. diff could work off of that directly, without the need to generate a whole duplicate bugdir. I'm stuck on how to handle upgrades though... Also removed trailing whitespace from all python files. --- libbe/storage/vcs/darcs.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'libbe/storage/vcs/darcs.py') diff --git a/libbe/storage/vcs/darcs.py b/libbe/storage/vcs/darcs.py index 97e31ff..9a371d9 100644 --- a/libbe/storage/vcs/darcs.py +++ b/libbe/storage/vcs/darcs.py @@ -76,7 +76,7 @@ class Darcs(base.VCS): def _vcs_detect(self, path): if self._u_search_parent_directories(path, "_darcs") != None : return True - return False + return False def _vcs_root(self, path): """Find the root of the deepest repository containing path.""" @@ -129,7 +129,7 @@ class Darcs(base.VCS): 'diff', '--unified', '--patch', revision, path, unicode_output=False) target_patch = output - + # '--output -' to be supported in GNU patch > 2.5.9 # but that hasn't been released as of June 30th, 2009. @@ -206,7 +206,7 @@ class Darcs(base.VCS): except IndexError: return None - + if libbe.TESTING == True: base.make_vcs_testcase_subclasses(Darcs, sys.modules[__name__]) -- cgit From 268713c0e2ed76edd84a2196b5c14fe1bc4ff08a Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Tue, 29 Dec 2009 10:39:09 -0500 Subject: Updated Darcs backend towards supporting .children(revision). ._vcs_isdir() and ._vcs_listdir() will need to parse the output of darcs show files [options] --patch REVISION PATH but both the --patch option and the PATH argument are new, and I can't get a recent enough version of Darcs to compile on my system. Theoretically they will work, but they remain untested for now. I don't think it's worth rolling my own darcs show files --patch REVISION to support earlier versions of Darcs, since the only solution I can think of now would be to check out the given revision and use os.walk() or some such, and that would be really ugly... Also added .version_cmp() for easy version comparison. Reindented ._vcs_get_file_contents() to remove trailing elses since the if clauses all contain returns. --- libbe/storage/vcs/darcs.py | 154 +++++++++++++++++++++++++++++++++------------ 1 file changed, 114 insertions(+), 40 deletions(-) (limited to 'libbe/storage/vcs/darcs.py') diff --git a/libbe/storage/vcs/darcs.py b/libbe/storage/vcs/darcs.py index 9a371d9..6d47ea5 100644 --- a/libbe/storage/vcs/darcs.py +++ b/libbe/storage/vcs/darcs.py @@ -53,9 +53,47 @@ class Darcs(base.VCS): def _vcs_version(self): status,output,error = self._u_invoke_client('--version') - num_part = output.split(' ')[0] - self.parsed_version = [int(i) for i in num_part.split('.')] - return output + return output.rstrip('\n') + + def version_cmp(self, *args): + """ + Compare the installed darcs version V_i with another version + V_o (given in *args). Returns + 1 if V_i > V_o, + 0 if V_i == V_o, and + -1 if V_i < V_o + >>> d = Darcs(repo='.') + >>> d._vcs_version = lambda : "2.3.1 (release)" + >>> d.version_cmp(2,3,1) + 0 + >>> d.version_cmp(2,3,2) + -1 + >>> d.version_cmp(2,3,0) + 1 + >>> d.version_cmp(3) + -1 + >>> d._vcs_version = lambda : "2.0.0pre2" + >>> d._parsed_version = None + >>> d.version_cmp(3) + Traceback (most recent call last): + ... + NotImplementedError: Cannot parse "2.0.0pre2" portion of Darcs version "2.0.0pre2" + invalid literal for int() with base 10: '0pre2' + """ + if not hasattr(self, '_parsed_version') \ + or self._parsed_version == None: + num_part = self._vcs_version().split(' ')[0] + try: + self._parsed_version = [int(i) for i in num_part.split('.')] + except ValueError, e: + raise NotImplementedError( + 'Cannot parse "%s" portion of Darcs version "%s"\n %s' + % (num_part, self._vcs_version(), str(e))) + cmps = [cmp(a,b) for a,b in zip(self._parsed_version, args)] + for c in cmps: + if c != 0: + return c + return 0 def _vcs_get_user_id(self): # following http://darcs.net/manual/node4.html#SECTION00410030000000000000 @@ -113,45 +151,81 @@ class Darcs(base.VCS): def _vcs_get_file_contents(self, path, revision=None): if revision == None: return base.VCS._vcs_get_file_contents(self, path, revision) + if self.version_cmp(2, 0, 0) == 1: + status,output,error = self._u_invoke_client( \ + 'show', 'contents', '--patch', revision, path) + return output + # Darcs versions < 2.0.0pre2 lack the 'show contents' command + + status,output,error = self._u_invoke_client( \ + 'diff', '--unified', '--from-patch', revision, path, + unicode_output=False) + major_patch = output + status,output,error = self._u_invoke_client( \ + 'diff', '--unified', '--patch', revision, path, + unicode_output=False) + target_patch = output + + # '--output -' to be supported in GNU patch > 2.5.9 + # but that hasn't been released as of June 30th, 2009. + + # Rewrite path to status before the patch we want + args=['patch', '--reverse', path] + status,output,error = self._u_invoke(args, stdin=major_patch) + # Now apply the patch we want + args=['patch', path] + status,output,error = self._u_invoke(args, stdin=target_patch) + + if os.path.exists(os.path.join(self.repo, path)) == True: + contents = base.VCS._vcs_get_file_contents(self, path) else: - if self.parsed_version[0] >= 2: - status,output,error = self._u_invoke_client( \ - 'show', 'contents', '--patch', revision, path) - return output + contents = '' + + # Now restore path to it's current incarnation + args=['patch', '--reverse', path] + status,output,error = self._u_invoke(args, stdin=target_patch) + args=['patch', path] + status,output,error = self._u_invoke(args, stdin=major_patch) + current_contents = base.VCS._vcs_get_file_contents(self, path) + return contents + + def _vcs_path(self, id, revision): + return self._u_find_id(id, revision) + + def _vcs_isdir(self, path, revision): + if self.version_cmp(2, 3, 1) == 1: + # Sun Nov 15 20:32:06 EST 2009 thomashartman1@gmail.com + # * add versioned show files functionality (darcs show files -p 'some patch') + status,output,error = self._u_invoke_client( \ + 'show', 'files', '--no-files', '--patch', revision) + children = output.rstrip('\n').splitlines() + rpath = '.' + children = [self._u_rel_path(c, rpath) for c in children] + if path in children: + return True + return False + # Darcs versions <= 2.3.1 lack the --patch option for 'show files' + raise NotImplementedError + + def _vcs_listdir(self, path, revision): + if self.version_cmp(2, 3, 1) == 1: + # Sun Nov 15 20:32:06 EST 2009 thomashartman1@gmail.com + # * add versioned show files functionality (darcs show files -p 'some patch') + # Wed Dec 9 05:42:21 EST 2009 Luca Molteni + # * resolve issue835 show file with file directory arguments + path = path.rstrip(os.path.sep) + status,output,error = self._u_invoke_client( \ + 'show', 'files', '--patch', revision, path) + files = output.rstrip('\n').splitlines() + if path == '.': + descendents = [self._u_rel_path(f, path) for f in files + if f != '.'] else: - # Darcs versions < 2.0.0pre2 lack the 'show contents' command - - status,output,error = self._u_invoke_client( \ - 'diff', '--unified', '--from-patch', revision, path, - unicode_output=False) - major_patch = output - status,output,error = self._u_invoke_client( \ - 'diff', '--unified', '--patch', revision, path, - unicode_output=False) - target_patch = output - - # '--output -' to be supported in GNU patch > 2.5.9 - # but that hasn't been released as of June 30th, 2009. - - # Rewrite path to status before the patch we want - args=['patch', '--reverse', path] - status,output,error = self._u_invoke(args, stdin=major_patch) - # Now apply the patch we want - args=['patch', path] - status,output,error = self._u_invoke(args, stdin=target_patch) - - if os.path.exists(os.path.join(self.repo, path)) == True: - contents = base.VCS._vcs_get_file_contents(self, path) - else: - contents = '' - - # Now restore path to it's current incarnation - args=['patch', '--reverse', path] - status,output,error = self._u_invoke(args, stdin=target_patch) - args=['patch', path] - status,output,error = self._u_invoke(args, stdin=major_patch) - current_contents = base.VCS._vcs_get_file_contents(self, path) - return contents + descendents = [self._u_rel_path(f, path) for f in files + if f.startswith(path)] + return [f for f in descendents if f.count(os.path.sep) == 0] + # Darcs versions <= 2.3.1 lack the --patch option for 'show files' + raise NotImplementedError def _vcs_commit(self, commitfile, allow_empty=False): id = self.get_user_id() -- cgit