3 bup_python="$(dirname "$0")/bup-python" || exit $?
4 exec "$bup_python" "$0" ${1+"$@"}
8 from __future__ import absolute_import, print_function
9 import sys, os, stat, fnmatch
11 from bup import options, git, shquote, ls, vfs
12 from bup.helpers import chunkyreader, handle_ctrl_c, log
13 from bup.repo import LocalRepo
18 class OptionError(Exception):
22 def do_ls(repo, args):
24 opt = ls.opts_from_cmdline(args, onabort=OptionError)
25 except OptionError as e:
28 return ls.within_repo(repo, opt)
31 def write_to_file(inf, outf):
32 for blob in chunkyreader(inf):
37 if os.isatty(sys.stdin.fileno()):
40 yield raw_input('bup> ')
42 print() # Clear the line for the terminal's next prompt
45 for line in sys.stdin:
49 def _completer_get_subs(repo, line):
50 (qtype, lastword) = shquote.unfinished_word(line)
51 (dir,name) = os.path.split(lastword)
52 dir_path = vfs.resolve(repo, dir or '/')
53 _, dir_item = dir_path[-1]
57 subs = tuple(dir_path + (entry,)
58 for entry in vfs.contents(repo, dir_item)
59 if (entry[0] != '.' and entry[0].startswith(name)))
60 return dir, name, qtype, lastword, subs
65 def completer(text, iteration):
70 line = readline.get_line_buffer()[:readline.get_endidx()]
71 if _last_line != line:
72 _last_res = _completer_get_subs(repo, line)
74 (dir, name, qtype, lastword, subs) = _last_res
75 if iteration < len(subs):
76 path = subs[iteration]
77 leaf_name, leaf_item = path[-1]
78 res = vfs.try_resolve(repo, leaf_name, parent=path[:-1])
79 leaf_name, leaf_item = res[-1]
80 fullname = os.path.join(*(name for name, item in res))
81 if stat.S_ISDIR(vfs.item_mode(leaf_item)):
82 ret = shquote.what_to_add(qtype, lastword, fullname+'/',
85 ret = shquote.what_to_add(qtype, lastword, fullname,
88 except Exception as e:
92 traceback.print_tb(sys.exc_traceback)
93 except Exception as e2:
94 log('Error printing traceback: %s\n' % e2)
95 log('\nError in completion: %s\n' % e)
101 o = options.Options(optspec)
102 (opt, flags, extra) = o.parse(sys.argv[1:])
104 git.check_repo_or_die()
107 pwd = vfs.resolve(repo, '/')
116 log('* readline module not available: line editing disabled.\n')
120 readline.set_completer_delims(' \t\n\r/')
121 readline.set_completer(completer)
122 if sys.platform.startswith('darwin'):
123 # MacOS uses a slightly incompatible clone of libreadline
124 readline.parse_and_bind('bind ^I rl_complete')
125 readline.parse_and_bind('tab: complete')
131 words = [word for (wordstart,word) in shquote.quotesplit(line)]
132 cmd = words[0].lower()
133 #log('execute: %r %r\n' % (cmd, parm))
136 # FIXME: respect pwd (perhaps via ls accepting resolve path/parent)
137 do_ls(repo, words[1:])
140 for parm in words[1:]:
141 res = vfs.resolve(repo, parm, parent=np)
142 _, leaf_item = res[-1]
144 raise Exception('%r does not exist'
145 % '/'.join(name for name, item in res))
146 if not stat.S_ISDIR(vfs.item_mode(leaf_item)):
147 raise Exception('%r is not a directory' % parm)
152 sys.stdout.write('/')
153 print('/'.join(name for name, item in pwd))
155 for parm in words[1:]:
156 res = vfs.resolve(repo, parm, parent=pwd)
157 _, leaf_item = res[-1]
159 raise Exception('%r does not exist' %
160 '/'.join(name for name, item in res))
161 with vfs.fopen(repo, leaf_item) as srcfile:
162 write_to_file(srcfile, sys.stdout)
164 if len(words) not in [2,3]:
166 raise Exception('Usage: get <filename> [localname]')
168 (dir,base) = os.path.split(rname)
169 lname = len(words)>2 and words[2] or base
170 res = vfs.resolve(repo, rname, parent=pwd)
171 _, leaf_item = res[-1]
173 raise Exception('%r does not exist' %
174 '/'.join(name for name, item in res))
175 with vfs.fopen(repo, leaf_item) as srcfile:
176 with open(lname, 'wb') as destfile:
177 log('Saving %r\n' % lname)
178 write_to_file(srcfile, destfile)
180 for parm in words[1:]:
181 (dir,base) = os.path.split(parm)
183 res = vfs.resolve(repo, dir, parent=pwd)
184 _, dir_item = res[-1]
186 raise Exception('%r does not exist' % dir)
187 for name, item in vfs.contents(repo, dir_item):
190 if fnmatch.fnmatch(name, base):
191 if stat.S_ISLNK(vfs.item_mode(item)):
192 deref = vfs.resolve(repo, name, parent=res)
193 deref_name, deref_item = deref[-1]
195 raise Exception('%r does not exist' %
196 '/'.join(name for name, item
199 with vfs.fopen(repo, item) as srcfile:
200 with open(name, 'wb') as destfile:
201 log('Saving %r\n' % name)
202 write_to_file(srcfile, destfile)
203 elif cmd == 'help' or cmd == '?':
204 # FIXME: move to stdout
205 log('Commands: ls cd pwd cat get mget help quit\n')
206 elif cmd in ('quit', 'exit', 'bye'):
210 raise Exception('no such command %r' % cmd)
211 except Exception as e:
213 log('error: %s\n' % e)