Package moap :: Package vcs :: Module darcs
[hide private]
[frames] | no frames]

Source Code for Module moap.vcs.darcs

  1  # -*- Mode: Python; test-case-name: moap.test.test_vcs_darcs -*- 
  2  # vi:si:et:sw=4:sts=4:ts=4 
  3   
  4  """ 
  5  Darcs functionality. 
  6  """ 
  7   
  8  import os 
  9  import commands 
 10  import re 
 11   
 12  from moap.util import util, log 
 13  from moap.vcs import vcs 
 14   
15 -def detect(path):
16 """ 17 Detect if the given source tree is using Darcs. 18 19 @return: True if the given path looks like a Darcs tree. 20 """ 21 # for darcs, we may have to walk up directories 22 # see http://www.darcs.net/manual/node9.html 23 if not os.path.exists(os.path.join(path, '_darcs')): 24 log.debug('darcs', 'Did not find _darcs directory under %s' % path) 25 return False 26 27 # some paths I found after an initialize and get 28 for n in ['inventories', 'prefs']: 29 if not os.path.exists(os.path.join(path, '_darcs', n)): 30 log.debug('darcs', 'Did not find _darcs/%s under %s' % (n, path)) 31 return False 32 33 return True
34
35 -class Darcs(vcs.VCS):
36 name = 'Darcs' 37
38 - def getUnknown(self, path):
39 # darcs has "query manifest" to list version-controlled files, 40 # and a toplevel .darcs-boring file listing comments and regexps 41 oldPath = os.getcwd() 42 43 versioned = [] 44 # output of this command starts with ./, filter that out 45 cmd = "darcs query manifest --repodir=%s" % path 46 output = commands.getoutput(cmd) 47 for line in output.split("\n"): 48 versioned.append(line[1 + len(os.path.sep):]) 49 self.debug('%d versioned files' % len(versioned)) 50 51 allFiles = [] 52 53 def walker(allFiles, dirname, fnames): 54 if not dirname.startswith(self.path): 55 fnames = [] 56 return 57 58 reldirname = dirname[len(os.path.join(self.path, '')):] 59 # copy fnames so we can remove from it safely 60 for fname in fnames[:]: 61 # ignore _darcs directory in toplevel 62 if dirname == self.path and fname == "_darcs": 63 fnames.remove(fname) 64 continue 65 # darcs doesn't list directories as part of manifest 66 if not os.path.isdir(os.path.join(dirname, fname)): 67 allFiles.append(os.path.join(reldirname, fname))
68 69 os.path.walk(self.path, walker, allFiles) 70 self.debug('%d total files' % len(allFiles)) 71 72 boringPath = os.path.join(self.path, '.darcs-boring') 73 boringRegExps = [] 74 if os.path.exists(boringPath): 75 boringRegExps = open(boringPath).readlines() 76 77 unversioned = [n for n in allFiles if n not in versioned] 78 self.debug('%d unversioned files' % len(unversioned)) 79 80 # now filter out based on the regexps 81 boring = [] 82 for exp in boringRegExps: 83 exp = exp.rstrip() 84 if not exp: 85 continue 86 if exp.startswith('#'): 87 continue 88 matcher = re.compile(exp) 89 for name in unversioned: 90 if matcher.match(name): 91 boring.append(name) 92 93 unignored = [n for n in unversioned if n not in boring] 94 self.debug('%d unignored files' % len(unignored)) 95 96 os.chdir(oldPath) 97 return unignored
98
99 - def ignore(self, paths, commit=True):
100 if not paths: 101 return 102 # FIXME: darcs allows regexp style, maybe our ignore should too 103 self.debug('ignoring %d paths' % len(paths)) 104 oldPath = os.getcwd() 105 os.chdir(self.path) 106 107 boring = os.path.join(self.path, '.darcs-boring') 108 addBoring = not os.path.exists(boring) 109 handle = open(boring, "a") 110 self.debug('adding %d paths to %s' % (len(paths), boring)) 111 for path in paths: 112 handle.write('%s\n' % path) 113 handle.close() 114 115 # FIXME: we should check if it is tracked, not if it exists; 116 # someone can have created it without adding it 117 if addBoring: 118 cmd = "darcs add .darcs-boring" 119 self.debug('Executing %s' % cmd) 120 os.system(cmd) 121 if commit: 122 cmd = "darcs record -am 'moap ignore' .darcs-boring" 123 self.debug('Executing %s' % cmd) 124 os.system(cmd) 125 126 os.chdir(oldPath)
127
128 - def commit(self, paths, message):
129 # again, to commit, we need to be in the working directory 130 # paths are absolute, so scrub them 131 oldPath = os.getcwd() 132 os.chdir(self.path) 133 134 temp = util.writeTemp([message, ]) 135 cmd = "darcs record -a --logfile=%s %s" % ( 136 temp, " ".join(paths)) 137 self.debug('running %s' % cmd) 138 status = os.system(cmd) 139 os.unlink(temp) 140 141 os.chdir(oldPath) 142 143 if status != 0: 144 return False 145 146 return True
147
148 - def diff(self, path):
149 # darcs diff only works when in the working directory 150 oldPath = os.getcwd() 151 os.chdir(path) 152 153 cmd = "darcs diff --unified" 154 self.debug('Running %s' % cmd) 155 output = commands.getoutput(cmd) 156 157 os.chdir(oldPath) 158 return output
159
160 - def getFileMatcher(self):
161 return re.compile('^diff -rN -u old-.*/(\S+)$')
162
163 - def update(self, path):
164 # FIXME: I don't see a way to pull just updates to the given path 165 cmd = "darcs pull %s" % self.path 166 status, output = commands.getstatusoutput(cmd) 167 code = os.WEXITSTATUS(status) 168 if code not in (0, 2): 169 # darcs pull returns error code 2 when 170 # darcs failed: No default repository to pull from, please specify 171 # one 172 # we let it pass 173 raise vcs.VCSException(output) 174 175 return output
176 177 VCSClass = Darcs 178