]> arthur.barton.de Git - bup.git/commitdiff
Port ls to vfs2
authorRob Browning <rlb@defaultvalue.org>
Sat, 7 Oct 2017 21:37:04 +0000 (16:37 -0500)
committerRob Browning <rlb@defaultvalue.org>
Sat, 16 Dec 2017 23:29:16 +0000 (17:29 -0600)
Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Tested-by: Rob Browning <rlb@defaultvalue.org>
cmd/ls-cmd.py
lib/bup/ls.py
t/test-ls.sh

index 377d2756958e829aba92b727a5b097c7ab068f57..913dab78d5bd585ff225f2392cff0996eba6860f 100755 (executable)
@@ -7,12 +7,11 @@ exec "$bup_python" "$0" ${1+"$@"}
 
 import sys
 
-from bup import git, vfs, ls
+from bup import git, ls
 
 
 git.check_repo_or_die()
-top = vfs.RefList(None)
 
 # Check out lib/bup/ls.py for the opt spec
-ret = ls.do_ls(sys.argv[1:], top, default='/', spec_prefix='bup ')
-sys.exit(ret)
+rc = ls.do_ls(sys.argv[1:], default='/', spec_prefix='bup ')
+sys.exit(rc)
index b52b188f1ec4d66067d17c6b2b4ff6b67aa26de8..0b5fb90426fdaca30753fb88361f8e8b55c2eea7 100644 (file)
@@ -1,45 +1,41 @@
 """Common code for listing files from a bup repository."""
 
-import copy, os.path, stat, sys, xstat
+from __future__ import print_function
+from itertools import chain
+from stat import S_ISDIR, S_ISLNK
+import copy, locale, os.path, stat, sys, xstat
 
-from bup import metadata, options, vfs
-from helpers import columnate, istty1, log
+from bup import metadata, options, vfs2 as vfs
+from bup.repo import LocalRepo
+from helpers import columnate, istty1, last, log
 
 
-def node_info(n, name,
+def item_info(item, name,
               show_hash = False,
               long_fmt = False,
               classification = None,
               numeric_ids = False,
               human_readable = False):
-    """Return a string containing the information to display for the node
-    n.  Classification may be "all", "type", or None."""
+    """Return a string containing the information to display for the VFS
+    item.  Classification may be "all", "type", or None.
+
+    """
     result = ''
-    if show_hash:
-        result += "%s " % n.hash.encode('hex')
+    if show_hash and hasattr(item, 'oid'):
+        result += '%s ' % item.oid.encode('hex')
     if long_fmt:
-        meta = copy.copy(n.metadata())
-        if meta:
-            meta.path = name
-            meta.size = n.size()
-        else:
-            # Fake it -- summary_str() is designed to handle a fake.
-            meta = metadata.Metadata()
-            meta.size = n.size()
-            meta.mode = n.mode
-            meta.path = name
-            meta.atime, meta.mtime, meta.ctime = n.atime, n.mtime, n.ctime
-            if stat.S_ISLNK(meta.mode):
-                meta.symlink_target = n.readlink()
+        meta = item.meta.copy()
+        meta.path = name
+        # FIXME: need some way to track fake vs real meta items?
         result += metadata.summary_str(meta,
-                                       numeric_ids = numeric_ids,
-                                       classification = classification,
-                                       human_readable = human_readable)
+                                       numeric_ids=numeric_ids,
+                                       classification=classification,
+                                       human_readable=human_readable)
     else:
         result += name
         if classification:
-            mode = n.metadata() and n.metadata().mode or n.mode
-            result += xstat.classification_str(mode, classification == 'all')
+            result += xstat.classification_str(item.meta.mode,
+                                               classification == 'all')
     return result
 
 
@@ -57,7 +53,7 @@ human-readable    print human readable file sizes (i.e. 3.9K, 4.7M)
 n,numeric-ids list numeric IDs (user, group, etc.) rather than names
 """
 
-def do_ls(args, pwd, default='.', onabort=None, spec_prefix=''):
+def do_ls(args, default='.', onabort=None, spec_prefix=''):
     """Output a listing of a file or directory in the bup repository.
 
     When a long listing is not requested and stdout is attached to a
@@ -86,47 +82,60 @@ def do_ls(args, pwd, default='.', onabort=None, spec_prefix=''):
         elif option in ('-A', '--almost-all'):
             show_hidden = 'almost'
 
-    L = []
-    def output_node_info(node, name):
-        info = node_info(node, name,
+    def item_line(item, name):
+        return item_info(item, name,
                          show_hash = opt.hash,
                          long_fmt = opt.l,
                          classification = classification,
                          numeric_ids = opt.numeric_ids,
                          human_readable = opt.human_readable)
-        if not opt.l and istty1:
-            L.append(info)
-        else:
-            print info
 
+    repo = LocalRepo()
     ret = 0
+    pending = []
     for path in (extra or [default]):
         try:
             if opt.directory:
-                n = pwd.lresolve(path)
+                resolved = vfs.lresolve(repo, path)
             else:
-                n = pwd.try_resolve(path)
+                # FIXME: deal with invalid symlinks i.e. old vfs try_resolve
+                resolved = vfs.resolve(repo, path)
 
-            if not opt.directory and stat.S_ISDIR(n.mode):
+            leaf_name, leaf_item = resolved[-1]
+            if not leaf_item:
+                log('error: cannot access %r in %r\n'
+                    % ('/'.join(name for name, item in resolved),
+                       path))
+                ret = 1
+                continue
+            if not opt.directory and S_ISDIR(vfs.item_mode(leaf_item)):
+                items = vfs.contents(repo, leaf_item)
                 if show_hidden == 'all':
-                    output_node_info(n, '.')
                     # Match non-bup "ls -a ... /".
-                    if n.parent:
-                        output_node_info(n.parent, '..')
-                    else:
-                        output_node_info(n, '..')
-                for sub in n:
-                    name = sub.name
-                    if show_hidden in ('almost', 'all') \
-                       or not len(name)>1 or not name.startswith('.'):
-                        output_node_info(sub, name)
+                    parent = resolved[-2] if len(resolved) > 1 else resolved[0]
+                    items = chain(items, (('..', parent[1]),))
+
+                items = ((x[0], vfs.augment_item_meta(repo, x[1],
+                                                      include_size=True))
+                         for x in items)
+                for sub_name, sub_item in sorted(items, key=lambda x: x[0]):
+                    if show_hidden != 'all' and sub_name == '.':
+                        continue
+                    if sub_name.startswith('.') and \
+                       show_hidden not in ('almost', 'all'):
+                        continue
+                    line = item_line(sub_item, sub_name)
+                    pending.append(line) if not opt.l and istty1 else print(line)
             else:
-                output_node_info(n, os.path.normpath(path))
-        except vfs.NodeError as e:
-            log('error: %s\n' % e)
+                leaf_item = vfs.augment_item_meta(repo, leaf_item,
+                                                  include_size=True)
+                line = item_line(leaf_item, os.path.normpath(path))
+                pending.append(line) if not opt.l and istty1 else print(line)
+        except vfs.IOError as ex:
+            log('bup: %s\n' % ex)
             ret = 1
 
-    if L:
-        sys.stdout.write(columnate(L, ''))
+    if pending:
+        sys.stdout.write(columnate(pending, ''))
 
     return ret
index e6d40fc644cc5e82d72deccdd8ae2d5339604004..cf9039e9c5f52fb16ee40061ac5b0bbde4960664 100755 (executable)
@@ -39,23 +39,19 @@ WVSTART "ls (short)"
 
 WVPASSEQ "$(WVPASS bup ls /)" "src"
 
-WVPASSEQ "$(WVPASS bup ls -A /)" ".commit
-.tag
+WVPASSEQ "$(WVPASS bup ls -A /)" ".tag
 src"
 
-WVPASSEQ "$(WVPASS bup ls -AF /)" ".commit/
-.tag/
+WVPASSEQ "$(WVPASS bup ls -AF /)" ".tag/
 src/"
 
 WVPASSEQ "$(WVPASS bup ls -a /)" ".
 ..
-.commit
 .tag
 src"
 
 WVPASSEQ "$(WVPASS bup ls -aF /)" "./
 ../
-.commit/
 .tag/
 src/"
 
@@ -105,31 +101,27 @@ WVPASSEQ "$(WVPASS bup ls -d src/latest)" "src/latest"
 WVSTART "ls (long)"
 
 WVPASSEQ "$(WVPASS bup ls -l / | tr -s ' ' ' ')" \
-"d--------- ?/? 0 1970-01-01 00:00 src"
+"drwxr-xr-x 0/0 0 1977-09-05 12:56 src"
 
 WVPASSEQ "$(WVPASS bup ls -lA / | tr -s ' ' ' ')" \
-"d--------- ?/? 0 1970-01-01 00:00 .commit
-d--------- ?/? 0 1970-01-01 00:00 .tag
-d--------- ?/? 0 1970-01-01 00:00 src"
+"drwxr-xr-x 0/0 0 1970-01-01 00:00 .tag
+drwxr-xr-x 0/0 0 1977-09-05 12:56 src"
 
 WVPASSEQ "$(WVPASS bup ls -lAF / | tr -s ' ' ' ')" \
-"d--------- ?/? 0 1970-01-01 00:00 .commit/
-d--------- ?/? 0 1970-01-01 00:00 .tag/
-d--------- ?/? 0 1970-01-01 00:00 src/"
+"drwxr-xr-x 0/0 0 1970-01-01 00:00 .tag/
+drwxr-xr-x 0/0 0 1977-09-05 12:56 src/"
 
 WVPASSEQ "$(WVPASS bup ls -la / | tr -s ' ' ' ')" \
-"d--------- ?/? 0 1970-01-01 00:00 .
-d--------- ?/? 0 1970-01-01 00:00 ..
-d--------- ?/? 0 1970-01-01 00:00 .commit
-d--------- ?/? 0 1970-01-01 00:00 .tag
-d--------- ?/? 0 1970-01-01 00:00 src"
+"drwxr-xr-x 0/0 0 1970-01-01 00:00 .
+drwxr-xr-x 0/0 0 1970-01-01 00:00 ..
+drwxr-xr-x 0/0 0 1970-01-01 00:00 .tag
+drwxr-xr-x 0/0 0 1977-09-05 12:56 src"
 
 WVPASSEQ "$(WVPASS bup ls -laF / | tr -s ' ' ' ')" \
-"d--------- ?/? 0 1970-01-01 00:00 ./
-d--------- ?/? 0 1970-01-01 00:00 ../
-d--------- ?/? 0 1970-01-01 00:00 .commit/
-d--------- ?/? 0 1970-01-01 00:00 .tag/
-d--------- ?/? 0 1970-01-01 00:00 src/"
+"drwxr-xr-x 0/0 0 1970-01-01 00:00 ./
+drwxr-xr-x 0/0 0 1970-01-01 00:00 ../
+drwxr-xr-x 0/0 0 1970-01-01 00:00 .tag/
+drwxr-xr-x 0/0 0 1977-09-05 12:56 src/"
 
 symlink_mode="$(WVPASS ls -l src/symlink | cut -b -10)" || exit $?
 socket_mode="$(WVPASS ls -l src/socket | cut -b -10)" || exit $?
@@ -140,6 +132,8 @@ symlink_date="$(WVPASS echo "$symlink_bup_info" \
   | WVPASS perl -ne 'm/.*? (\d+) (\d\d\d\d-\d\d-\d\d \d\d:\d\d)/ and print $2')" \
     || exit $?
 
+test "$symlink_date" || exit 1
+
 if test "$(uname -s)" != NetBSD; then
     symlink_size="$(WVPASS bup-python -c "import os
 print os.lstat('src/symlink').st_size")" || exit $?
@@ -165,7 +159,7 @@ $symlink_mode $user/$group $symlink_size $symlink_date symlink -> file"
 
 WVPASSEQ "$(bup ls -la src/latest | tr -s ' ' ' ')" \
 "drwx------ $user/$group 0 2009-10-03 23:48 .
-d--------- ?/? 0 1970-01-01 00:00 ..
+drwxr-xr-x 0/0 0 1977-09-05 12:56 ..
 -rw------- $user/$group 0 2009-10-03 23:48 .dotfile
 -rwx------ $user/$group 0 2009-10-03 23:48 executable
 prw------- $user/$group 0 2009-10-03 23:48 fifo
@@ -202,14 +196,14 @@ prw------- $uid/$gid 0 2009-10-03 23:48 fifo
 $socket_mode $uid/$gid 0 2009-10-03 23:48 socket
 $symlink_mode $uid/$gid $symlink_size $symlink_date symlink -> file"
 
-WVPASSEQ "$(bup ls -ld "src/latest/" | tr -s ' ' ' ')" \
+WVPASSEQ "$(bup ls -ld "src/latest" | tr -s ' ' ' ')" \
 "drwx------ $user/$group 0 2009-10-03 23:48 src/latest"
 
 
 WVSTART "ls (backup set - long)"
-WVPASSEQ "$(bup ls -l src | cut -d' ' -f 1-2)" \
-"l--------- ?/?
-l--------- ?/?"
+WVPASSEQ "$(bup ls -l --numeric-ids src | cut -d' ' -f 1-2)" \
+"drwxr-xr-x 0/0
+drwxr-xr-x 0/0"
 
 
 WVSTART "ls (dates TZ != UTC)"