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.io import byte_stream
13 from bup.helpers import chunkyreader, handle_ctrl_c, log
14 from bup.repo import LocalRepo
19 class OptionError(Exception):
23 def do_ls(repo, args, out):
25 opt = ls.opts_from_cmdline(args, onabort=OptionError)
26 except OptionError as e:
29 return ls.within_repo(repo, opt, out)
32 def write_to_file(inf, outf):
33 for blob in chunkyreader(inf):
38 if os.isatty(sys.stdin.fileno()):
41 yield raw_input('bup> ')
43 print() # Clear the line for the terminal's next prompt
46 for line in sys.stdin:
50 def _completer_get_subs(repo, line):
51 (qtype, lastword) = shquote.unfinished_word(line)
52 (dir,name) = os.path.split(lastword)
53 dir_path = vfs.resolve(repo, dir or '/')
54 _, dir_item = dir_path[-1]
58 subs = tuple(dir_path + (entry,)
59 for entry in vfs.contents(repo, dir_item)
60 if (entry[0] != '.' and entry[0].startswith(name)))
61 return dir, name, qtype, lastword, subs
66 def completer(text, iteration):
71 line = readline.get_line_buffer()[:readline.get_endidx()]
72 if _last_line != line:
73 _last_res = _completer_get_subs(repo, line)
75 (dir, name, qtype, lastword, subs) = _last_res
76 if iteration < len(subs):
77 path = subs[iteration]
78 leaf_name, leaf_item = path[-1]
79 res = vfs.try_resolve(repo, leaf_name, parent=path[:-1])
80 leaf_name, leaf_item = res[-1]
81 fullname = os.path.join(*(name for name, item in res))
82 if stat.S_ISDIR(vfs.item_mode(leaf_item)):
83 ret = shquote.what_to_add(qtype, lastword, fullname+'/',
86 ret = shquote.what_to_add(qtype, lastword, fullname,
89 except Exception as e:
93 traceback.print_tb(sys.exc_traceback)
94 except Exception as e2:
95 log('Error printing traceback: %s\n' % e2)
96 log('\nError in completion: %s\n' % e)
100 bup ftp [commands...]
102 o = options.Options(optspec)
103 (opt, flags, extra) = o.parse(sys.argv[1:])
105 git.check_repo_or_die()
108 out = byte_stream(sys.stdout)
110 pwd = vfs.resolve(repo, '/')
119 log('* readline module not available: line editing disabled.\n')
123 readline.set_completer_delims(' \t\n\r/')
124 readline.set_completer(completer)
125 if sys.platform.startswith('darwin'):
126 # MacOS uses a slightly incompatible clone of libreadline
127 readline.parse_and_bind('bind ^I rl_complete')
128 readline.parse_and_bind('tab: complete')
134 words = [word for (wordstart,word) in shquote.quotesplit(line)]
135 cmd = words[0].lower()
136 #log('execute: %r %r\n' % (cmd, parm))
139 # FIXME: respect pwd (perhaps via ls accepting resolve path/parent)
140 sys.stdout.flush() # FIXME: remove when we finish py3 support
141 do_ls(repo, words[1:], out)
144 for parm in words[1:]:
145 res = vfs.resolve(repo, parm, parent=np)
146 _, leaf_item = res[-1]
148 raise Exception('%r does not exist'
149 % '/'.join(name for name, item in res))
150 if not stat.S_ISDIR(vfs.item_mode(leaf_item)):
151 raise Exception('%r is not a directory' % parm)
156 sys.stdout.write('/')
157 print('/'.join(name for name, item in pwd))
159 for parm in words[1:]:
160 res = vfs.resolve(repo, parm, parent=pwd)
161 _, leaf_item = res[-1]
163 raise Exception('%r does not exist' %
164 '/'.join(name for name, item in res))
165 with vfs.fopen(repo, leaf_item) as srcfile:
166 write_to_file(srcfile, sys.stdout)
168 if len(words) not in [2,3]:
170 raise Exception('Usage: get <filename> [localname]')
172 (dir,base) = os.path.split(rname)
173 lname = len(words)>2 and words[2] or base
174 res = vfs.resolve(repo, rname, parent=pwd)
175 _, leaf_item = res[-1]
177 raise Exception('%r does not exist' %
178 '/'.join(name for name, item in res))
179 with vfs.fopen(repo, leaf_item) as srcfile:
180 with open(lname, 'wb') as destfile:
181 log('Saving %r\n' % lname)
182 write_to_file(srcfile, destfile)
184 for parm in words[1:]:
185 (dir,base) = os.path.split(parm)
187 res = vfs.resolve(repo, dir, parent=pwd)
188 _, dir_item = res[-1]
190 raise Exception('%r does not exist' % dir)
191 for name, item in vfs.contents(repo, dir_item):
194 if fnmatch.fnmatch(name, base):
195 if stat.S_ISLNK(vfs.item_mode(item)):
196 deref = vfs.resolve(repo, name, parent=res)
197 deref_name, deref_item = deref[-1]
199 raise Exception('%r does not exist' %
200 '/'.join(name for name, item
203 with vfs.fopen(repo, item) as srcfile:
204 with open(name, 'wb') as destfile:
205 log('Saving %r\n' % name)
206 write_to_file(srcfile, destfile)
207 elif cmd == 'help' or cmd == '?':
208 # FIXME: move to stdout
209 log('Commands: ls cd pwd cat get mget help quit\n')
210 elif cmd in ('quit', 'exit', 'bye'):
214 raise Exception('no such command %r' % cmd)
215 except Exception as e:
217 log('error: %s\n' % e)