Commits

ZyX_I committed 7cc1835

@%aurum/drivers/bazaar: Added bzrlib version of set_cs_prop
Resolved sorting issues

Comments (0)

Files changed (4)

autoload/aurum/drivers/bazaar.vim

 function s:bzr.gettiphex(repo)
     return a:repo.functions.getrevhex(a:repo, '-1')
 endfunction
-"▶1 getstatdict :: repo, args, kwargs → statdict
-let s:emptystatdict=extend({'renamed': []}, deepcopy(s:_r.utils.emptystatdct))
-function s:F.getstatdict(repo, args, kwargs)
+"▶1 getstatdict :: repo, args, kwargs, renamed → statdict
+let s:emptystatdict=extend({'renames': {}}, deepcopy(s:_r.utils.emptystatdct))
+function s:F.getstatdict(repo, args, kwargs, renamed)
     let lines=s:F.bzr(a:repo, 'status', a:args,
                 \      extend({'no-classify': 1, 'no-pending': 1, 'short': 1},
                 \             a:kwargs),
                 \      0)[:-2]
     let curstatus=0
-    let statdict=deepcopy(s:emptystatdict)
+    if a:renamed
+        let statdict=deepcopy(s:emptystatdict)
+    else
+        let statdict=deepcopy(s:_r.utils.emptystatdct)
+    endif
     while !empty(lines)
         let line=remove(lines, 0)
         let status=line[:2]
         endif
         let file=line[4:]
         if status[0] is# 'R'
-            let statdict.renamed+=[file]
-            let curstatus='renamed'
+            let idx=stridx(file, ' => ')
+            if idx==-1
+                call s:_f.throw('rene', file)
+            elseif idx==0
+                call s:_f.throw('renze', file)
+            endif
+            let old=file[:(idx-1)]
+            let new=file[idx+4:]
+            if empty(new)
+                call s:_f.throw('renz2e', file)
+            endif
+            if a:renamed
+                let statdict.renames[new] = old
+            endif
+            let statdict.removed += [old]
+            let statdict.added   += [new]
+            let curstatus='added'
         elseif status[0] is# ' '
             if status[1] is# 'N'
                 let statdict.added    += [file]
     endwhile
     return statdict
 endfunction
-"▶1 getrenames :: statdict → renames
-function s:F.getrenames(statdict)
-    if !has_key(a:statdict, 'renamed')
-        return {}
-    endif
-    let renames={}
-    for rename in a:statdict.renamed
-        let idx=stridx(rename, " => ")
-        if idx==-1
-            call s:_f.throw('rene', rename)
-        elseif idx==0
-            call s:_f.throw('renze', rename)
-        endif
-        let old=rename[:(idx-1)]
-        let new=rename[idx+4:]
-        try
-            let renames[new]=old
-        catch /^Vim(let):E713:/
-            call s:_f.throw('renz2e', rename)
-        endtry
-    endfor
-    return renames
+"▶1 bzr.setcsprop :: repo, cs, propname → propvalue
+if s:usepythondriver "▶2
+function s:bzr.setcsprop(repo, cs, prop)
+    try
+        execute s:pya.'get_cs_prop(vim.eval("a:repo.path"), '.
+                    \             'vim.eval("a:cs.hex"), '.
+                    \             'vim.eval("a:prop"))'
+    endtry
 endfunction
-"▶1 bzr.setcsprop :: repo, cs, propname → propvalue
+else "▶2
 function s:bzr.setcsprop(repo, cs, prop)
     if a:prop is# 'allfiles'
         let r=s:_r.utils.nullnl(
                     \        'lsf', a:cs.hex))[:-2]
     elseif       a:prop is# 'renames' || a:prop is# 'changes' ||
                 \a:prop is# 'files'   || a:prop is# 'removes'
-        let statdict=s:F.getstatdict(a:repo, [], {'change': 'revid:'.a:cs.hex})
+        let statdict=s:F.getstatdict(a:repo, [], {'change': 'revid:'.a:cs.hex},
+                    \                1)
         let a:cs.removes  = copy(statdict.removed)
         let a:cs.files    = statdict.added+statdict.modified
-        let a:cs.renames  = s:F.getrenames(statdict)
-        let a:cs.removes += sort(values(a:cs.renames))
-        let a:cs.files   += sort(keys(  a:cs.renames))
+        let a:cs.renames  = statdict.renames
         let a:cs.changes  = a:cs.removes+a:cs.files
         return a:cs[a:prop]
     endif
     let a:cs[a:prop]=r
     return r
 endfunction
+endif
 "▶1 bzr.status :: repo[, rev1[, rev2[, files[, clean[, ign]]]]] → {type:[file]}
 if s:usepythondriver "▶2
 let s:revargsexpr='v:val is 0? '.
                 \                   ({'revision': a:1.'..'}):
                 \                ((a:0>1 && a:2 isnot 0)?
                 \                   ({'revision': a:2.'..'}):
-                \                   ({})))))
+                \                   ({})))), 0)
     let r=deepcopy(statdict)
-    let renames=s:F.getrenames(statdict)
-    call remove(r, 'renamed')
-    call filter(r.modified, '!has_key(renames, v:val)')
     if a:0>2 && !empty(a:3)
-        let r.added   += sort(filter(keys(renames),   'index(a:3, v:val)!=-1'))
-        let r.removed += sort(filter(values(renames), 'index(a:3, v:val)!=-1'))
-    else
-        let r.added   += sort(keys(renames))
-        let r.removed += sort(values(renames))
+        " getstatdict may have added unneeded information for renamed files
+        call filter(r.added,   'index(a:3, v:val)!=-1')
+        call filter(r.removed, 'index(a:3, v:val)!=-1')
     endif
     if a:0>1 && a:1 is 0 && a:2 isnot 0
         let [r.deleted, r.unknown]=[r.unknown, r.deleted]
         let r.clean=filter(allfiles, 'index(files, v:val)==-1')
     endif
     " Ignored files are listed in “bzr status” output, but only if they are 
-    " specified on the command-line. Bazaar really has good documentation:
-    " “bzr help status” does not have anything about “missing”, “ignored” and 
-    " “nonexistent” statuses or different behavior for explicitely specified 
-    " paths.
+    " specified on the command-line.
     if (a:0>4 && a:5 && a:1 is 0 && a:2 is 0 && empty(a:3))
         let r.ignored=s:_r.utils.nullnl(
                     \ s:F.bzr(a:repo, 'ls', args, {'ignored': 1, 'null': 1}, 2,
     " XXX Bazaar annotation respects renames, but it does not show old filename, 
     "     thus rename information is to be used
     for [id, lists] in items(idamap)
-        let renames=s:F.getrenames(s:F.getstatdict(a:repo, ['--', a:file],
-                    \                              {'revision': a:rev.'..'.id}))
+        let renames=s:F.getstatdict(a:repo, ['--', a:file],
+                    \                       {'revision': a:rev.'..'.id},
+                    \               1).renames
         let file=get(renames, a:file, a:file)
         call map(lists, 'insert(v:val, '.string(file).')')
     endfor
 |aurum-rf-getcsprop|(…, "children") requires at least mercurial-1.7 or manual 
     preceding |aurum-rf-getchangesets| call. Thus many Next mappings do not 
     work.
-|aurum-rf-astatus| in non-python version supports only 
+|aurum-rf-astatus| in non-python version supports only 
     status(repo,0,0,[file],1,1) calls.
 |aurum-rf-agetcs| is absent in non-python version of driver.
-|aurum-rf-agetrepoprop| in non-python version supports only “branch” property.
+|aurum-rf-agetrepoprop| in “non-python” version supports only “branch” 
+    property.
 *aurum-rf-svnrev* exists and produces svn revision number out of repository 
     object and mercurial revision specification.
 *aurum-rf-githex* exists and produces git sha1 out of repository object and 
 |aurum-rf-diffname| will work incorrectly if filenames containing “' => '” 
     were renamed.
 |aurum-repo.iterfuncs| is missing (yet).
-|aurum-rf-astatus| supports only status(repo,0,0,[file],1,1) calls.
+|aurum-rf-astatus| in “non-python” version supports only 
+    status(repo,0,0,[file],1,1) calls.
 |aurum-rf-agetcs| is absent.
-|aurum-rf-agetrepoprop| supports only “branch” property.
+|aurum-rf-agetrepoprop| in “non-python” version supports only “branch” 
+    property.
 
 ==============================================================================
 11. Changelog                                                *aurum-changelog*

python/aurum/aubazaar.py

         with(bzrlib.initialize()):
             return func(*args, **kwargs)
     f.__name__ = func.__name__
+    globals()[func.__name__+'_unchanged'] = func
     return f
 
 outermethod      = outermethodgen(g_repo, flush)
 
 repo_props={
         'branch':        lambda repo: repo.branch.nick,
-        'url':           lambda repo: str(   repo.branch.get_push_location()
-                                          or repo.branch.get_parent()),
+        'url':           lambda repo: (   repo.branch.get_push_location()
+                                       or repo.branch.get_parent()).encode('utf-8'),
         'bookmarkslist': lambda repo: [],
         'brancheslist':  lambda repo: [],
         'tagslist':      lambda repo: sorted_str_keys(repo.branch.tags.get_tag_dict()),
                 bzrmethod(
                 get_repo_prop_gen(repo_props, pathattr='basedir'))))
 
+class ReadLock(object):
+    def __init__(self, o):
+        self.o = o
+
+    def __enter__(self):
+        self.o.lock_read()
+
+    def __exit__(self, *args):
+        self.o.unlock()
+
+def get_all_files(repo, revid):
+    tree = repo.branch.repository.revision_tree(revid)
+    with ReadLock(tree):
+        return list((item[0].encode('utf-8') for item in tree.list_files()))
+
+@outermethod
+@autoexportmethod(var='a:cs', utf=False)
+@bzrmethod
+def get_cs_prop(repo, rev, prop):
+    revid = g_revid(repo, rev)
+    if prop in set(('files', 'removes', 'changes', 'renames')):
+        cs = repo.branch.repository.get_revision(revid)
+        if cs.parent_ids:
+            status = get_status_unchanged(repo, rev1=cs.parent_ids[0], rev2=revid, renamed=True)
+            return { 'renames': status['renames'],
+                       'files': status['added']+status['modified'],
+                     'removes': status['removed'],
+                     'changes': status['removed']+status['added']+status['modified'],
+                   }
+        else:
+            allfiles = get_all_files(repo, revid)
+            return {'renames': {}, 'files': allfiles, 'removes': [], 'changes': allfiles}
+    elif prop=='allfiles':
+        return {'allfiles': get_all_files(repo, revid)}
+
 class StatusReporter(object):
-    __slots__ = ('status', 'repo', 'ignored', 'files')
+    __slots__ = ('status', 'renames', 'repo', 'ignored', 'files', 'renamed')
 
-    def __init__(self, repo, ignored, files):
+    def __init__(self, repo, ignored, files, renamed):
         self.status  = emptystatdct()
+        self.renames = {}
         self.repo    = repo
         self.ignored = ignored
         self.files   = files
+        self.renamed = renamed
 
     def report(self, file_id, paths, track_ch, renamed, modified, exe_ch, kind):
         if paths[1] == '':
             return
         if track_ch == 'unchanged':
             if renamed:
+                if self.renamed:
+                    self.renames[paths[1].encode('utf-8')] = paths[0].encode('utf-8')
                 if paths[0] in self.files:
                     self.status['removed' ].append(paths[0])
                 if paths[1] in self.files:
             else:
                 self.status['unknown'].append(paths[1])
 
-class ReadLock(object):
-    def __init__(self, o):
-        self.o = o
-
-    def __enter__(self):
-        self.o.lock_read()
-
-    def __exit__(self, *args):
-        self.o.unlock()
-
 class ContainsEverything(object):
     @staticmethod
     def __contains__(o):
 @outermethod
 @autoexportmethod()
 @bzrmethod
-def get_status(repo, rev1=None, rev2=None, files=None, clean=None, ignored=None):
+def get_status(repo, rev1=None, rev2=None, files=None, clean=None, ignored=None, renamed=False):
     if not files:
         files = None
 
     old = repo.branch.repository.revision_tree(g_revid(repo, rev1)) if rev1 else repo.basis_tree()
     new = repo.branch.repository.revision_tree(g_revid(repo, rev2)) if rev2 else repo
 
-    reporter = StatusReporter(repo, ignored, set(files) if files else ContainsEverything())
+    reporter = StatusReporter(repo, ignored, set(files) if files else ContainsEverything(), renamed)
 
     with ReadLock(repo), ReadLock(old), ReadLock(new):
         changes  = new.iter_changes(old, clean, files, require_versioned=False,
 
     r = reporter.status
 
+    if renamed:
+        if reverse:
+            r['renames']=dict(((value, key) for key, value in reporter.renames.iteritems()))
+        else:
+            r['renames']=reporter.renames
+
     if reverse:
         r['deleted'], r['unknown'] = r['unknown'], r['deleted']
         r['added'],   r['removed'] = r['removed'], r['added']

Binary file modified.

Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.