def do_switch(self, revision_to_update_to, update_target, recurse, switch_url, update_editor, depth=None): args = [] if revision_to_update_to is None or revision_to_update_to == -1: args.append([]) else: args.append([revision_to_update_to]) args.append(update_target) args.append(recurse) args.append(switch_url) if depth is not None: args.append(literal(depth)) self.busy = True try: self.send_msg([literal("switch"), args]) self._recv_ack() return Reporter(self, update_editor) except BaseException: self.busy = False raise
def __init__(self, url, progress_cb=None, auth=None, config=None, client_string_func=None, open_tmp_file_func=None): self.url = url (type, opaque) = urllib.splittype(url) assert type in ("svn", "svn+ssh") (host, path) = urllib.splithost(opaque) self._progress_cb = progress_cb self._auth = auth self._config = config self._client_string_func = client_string_func # open_tmp_file_func is ignored, as it is not needed for svn:// if type == "svn": (recv_func, send_func) = self._connect(host) else: (recv_func, send_func) = self._connect_ssh(host) super(SVNClient, self).__init__(recv_func, send_func) (min_version, max_version, _, self._server_capabilities) = self._recv_greeting() self.send_msg([max_version, [literal(x) for x in CAPABILITIES if x in self._server_capabilities], self.url]) (self._server_mechanisms, mech_arg) = self._unpack() if self._server_mechanisms != []: # FIXME: Support other mechanisms as well self.send_msg([literal("ANONYMOUS"), [base64.b64encode("anonymous@%s" % socket.gethostname())]]) self.recv_msg() msg = self._unpack() if len(msg) > 2: self._server_capabilities += msg[2] (self._uuid, self._root_url) = msg[0:2] self.busy = False
def do_diff(self, revision_to_update, diff_target, versus_url, diff_editor, recurse=True, ignore_ancestry=False, text_deltas=False, depth=None): args = [] if revision_to_update is None or revision_to_update == -1: args.append([]) else: args.append([revision_to_update]) args += [ diff_target, recurse, ignore_ancestry, versus_url, text_deltas ] if depth is not None: args.append(literal(depth)) self.busy = True try: self.send_msg([literal("diff"), args]) self._recv_ack() return Reporter(self, diff_editor) except BaseException: self.busy = False raise
def send_textdelta(delta): if delta is None: self.conn.send_msg([literal("textdelta-end"), [self.id]]) else: self.conn.send_msg([ literal("textdelta-chunk"), [self.id, pack_svndiff0_window(delta)] ])
def send_revision(revno, author, date, message, changed_paths=None): changes = [] if changed_paths is not None: for p, (action, cf, cr) in changed_paths.iteritems(): if cf is not None: changes.append((p, literal(action), (cf, cr))) else: changes.append((p, literal(action), ())) self.send_msg([changes, revno, [author], [date], [message]])
def __init__(self, backend, recv_fn, send_fn, logf=None): self.backend = backend self._stop = False self._logf = logf super(SVNServer, self).__init__(recv_fn, send_fn) self.send_success( MIN_VERSION, MAX_VERSION, [literal(x) for x in MECHANISMS], [literal(x) for x in CAPABILITIES])
def log(self, paths, start, end, limit=0, discover_changed_paths=True, strict_node_history=True, include_merged_revisions=True, revprops=None): args = [paths] if start is None or start == -1: args.append([]) else: args.append([start]) if end is None or end == -1: args.append([]) else: args.append([end]) args.append(discover_changed_paths) args.append(strict_node_history) args.append(limit) args.append(include_merged_revisions) if revprops is None: args.append(literal("all-revprops")) args.append([]) else: args.append(literal("revprops")) args.append(revprops) self.send_msg([literal("log"), args]) self._recv_ack() while True: msg = self.recv_msg() if msg == "done": break paths = {} for p, action, cfd in msg[0]: if len(cfd) == 0: paths[p] = (str(action), None, -1) else: paths[p] = (str(action), cfd[0], cfd[1]) if len(msg) > 5: has_children = msg[5] else: has_children = None if len(msg) > 6 and msg[6]: revno = None else: revno = msg[1] # noqa: F841 # TODO(jelmer): Do something with revno revprops = {} if len(msg[2]) != 0: revprops[properties.PROP_REVISION_AUTHOR] = msg[2][0] if len(msg[3]) != 0: revprops[properties.PROP_REVISION_DATE] = msg[3][0] if len(msg[4]) != 0: revprops[properties.PROP_REVISION_LOG] = msg[4][0] if len(msg) > 8: revprops.update(dict(msg[8])) yield paths, msg[1], revprops, has_children self._unpack()
def apply_textdelta(self, base_checksum=None): self._is_last_open() if base_checksum is None: base_check = [] else: base_check = [base_checksum] self.conn.send_msg([literal("apply-textdelta"), [self.id, base_check]]) self.conn.send_msg([literal("textdelta-chunk"), [self.id, SVNDIFF0_HEADER]]) def send_textdelta(delta): if delta is None: self.conn.send_msg([literal("textdelta-end"), [self.id]]) else: self.conn.send_msg([literal("textdelta-chunk"), [self.id, pack_svndiff0_window(delta)]]) return send_textdelta
def replay(self, revision, low_water_mark, update_editor, send_deltas=True): self.send_msg([literal("replay"), [revision, low_water_mark, send_deltas]]) self._recv_ack() feed_editor(self, update_editor) self._unpack()
def get_locations(self, path, peg_revnum, revnums): self.send_ack() locations = self.repo_backend.get_locations(path, peg_revnum, revnums) for rev, path in locations.iteritems(): self.send_msg([rev, path]) self.send_msg(literal("done")) self.send_success()
def change_prop(self, name, value): self._is_last_open() if value is None: value = [] else: value = [value] self.conn.send_msg([literal("change-file-prop"), [self.id, name, value]])
def change_rev_prop(self, rev, name, value): args = [rev, name] if value is not None: args.append(value) self.send_msg([literal("change-rev-prop"), args]) self._recv_ack() self._unparse()
def log(self, target_path, start_rev, end_rev, changed_paths, strict_node, limit=None, include_merged_revisions=False, all_revprops=None, revprops=None): def send_revision(revno, author, date, message, changed_paths=None): changes = [] if changed_paths is not None: for p, (action, cf, cr) in changed_paths.iteritems(): if cf is not None: changes.append((p, literal(action), (cf, cr))) else: changes.append((p, literal(action), ())) self.send_msg([changes, revno, [author], [date], [message]]) self.send_ack() if len(start_rev) == 0: start_revnum = None else: start_revnum = start_rev[0] if len(end_rev) == 0: end_revnum = None else: end_revnum = end_rev[0] self.repo_backend.log(send_revision, target_path, start_revnum, end_revnum, changed_paths, strict_node, limit) self.send_msg(literal("done")) self.send_success()
def rev_prop(self, revision, name): self.send_msg([literal("rev-prop"), [revision, name]]) self._recv_ack() ret = self._unpack() if len(ret) == 0: return None else: return ret[0]
def get_lock(self, path): self.send_msg([literal("get-lock"), [path]]) self._recv_ack() ret = self._unpack() if len(ret) == 0: return None else: return ret[0]
def close(self, checksum=None): self._is_last_open() self.conn._open_ids.pop() if checksum is None: checksum = [] else: checksum = [checksum] self.conn.send_msg([literal("close-file"), [self.id, checksum]])
def get_dir(self, path, revision=-1, dirent_fields=0, want_props=True, want_contents=True): args = [path] if revision is None or revision == -1: args.append([]) else: args.append([revision]) args += [want_props, want_contents] fields = [] if dirent_fields & DIRENT_KIND: fields.append(literal("kind")) if dirent_fields & DIRENT_SIZE: fields.append(literal("size")) if dirent_fields & DIRENT_HAS_PROPS: fields.append(literal("has-props")) if dirent_fields & DIRENT_CREATED_REV: fields.append(literal("created-rev")) if dirent_fields & DIRENT_TIME: fields.append(literal("time")) if dirent_fields & DIRENT_LAST_AUTHOR: fields.append(literal("last-author")) args.append(fields) self.send_msg([literal("get-dir"), args]) self._recv_ack() ret = self._unpack() fetch_rev = ret[0] props = dict(ret[1]) dirents = {} for d in ret[2]: entry = unmarshall_dirent(d) dirents[entry["name"]] = entry return (dirents, fetch_rev, props)
def do_diff(self, revision_to_update, diff_target, versus_url, diff_editor, recurse=True, ignore_ancestry=False, text_deltas=False, depth=None): args = [] if revision_to_update is None or revision_to_update == -1: args.append([]) else: args.append([revision_to_update]) args += [diff_target, recurse, ignore_ancestry, versus_url, text_deltas] if depth is not None: args.append(literal(depth)) self.busy = True try: self.send_msg([literal("diff"), args]) self._recv_ack() return Reporter(self, diff_editor) except: self.busy = False raise
def open_root(self, base_revision=None): id = generate_random_id() if base_revision is None: baserev = [] else: baserev = [base_revision] self.conn.send_msg([literal("open-root"), [baserev, id]]) self.conn._open_ids = [] return DirectoryEditor(self.conn, id)
def add_directory(self, path, copyfrom_path=None, copyfrom_rev=-1): self._is_last_open() child = generate_random_id() if copyfrom_path is not None: copyfrom_data = [copyfrom_path, copyfrom_rev] else: copyfrom_data = [] self.conn.send_msg([literal("add-dir"), [path, self.id, child, copyfrom_data]]) return DirectoryEditor(self.conn, child)
def check_path(self, path, revision=None): args = [path] if revision is None or revision == -1: args.append([]) else: args.append([revision]) self.send_msg([literal("check-path"), args]) self._recv_ack() ret = self._unpack()[0] return {"dir": NODE_DIR, "file": NODE_FILE, "unknown": NODE_UNKNOWN, "none": NODE_NONE}[ret]
def link_path(self, path, url, rev, start_empty=False, lock_token=None, depth=None): args = [path, url, rev, start_empty] if lock_token is not None: args.append([lock_token]) else: args.append([]) if depth is not None: args.append(depth) self.conn.send_msg([literal("link-path"), args])
def check_path(self, path, rev): if len(rev) == 0: revnum = None else: revnum = rev[0] kind = self.repo_backend.check_path(path, revnum) self.send_ack() self.send_success(literal({NODE_NONE: "none", NODE_DIR: "dir", NODE_FILE: "file", NODE_UNKNOWN: "unknown"}[kind]))
def do_update(self, revision_to_update_to, update_target, recurse, update_editor, depth=None): args = [] if revision_to_update_to is None or revision_to_update_to == -1: args.append([]) else: args.append([revision_to_update_to]) args.append(update_target) args.append(recurse) if depth is not None: args.append(literal(depth)) self.busy = True try: self.send_msg([literal("update"), args]) self._recv_ack() return Reporter(self, update_editor) except: self.busy = False raise
def replay_range(self, start_revision, end_revision, low_water_mark, cbs, send_deltas=True): self.send_msg([literal("replay-range"), [start_revision, end_revision, low_water_mark, send_deltas]]) self._recv_ack() for i in range(start_revision, end_revision+1): msg = self.recv_msg() assert msg[0] == "revprops" edit = cbs[0](i, dict(msg[1])) feed_editor(self, edit) cbs[1](i, dict(msg[1]), edit) self._unpack()
def get_locations(self, path, peg_revision, location_revisions): self.send_msg([literal("get-locations"), [path, peg_revision, location_revisions]]) self._recv_ack() ret = {} while True: msg = self.recv_msg() if msg == "done": break ret[msg[0]] = msg[1] self._unparse() return ret
def get_commit_editor(self, revprops, callback=None, lock_tokens=None, keep_locks=False): args = [revprops[properties.PROP_REVISION_LOG]] if lock_tokens is not None: args.append(lock_tokens.items()) else: args.append([]) args.append(keep_locks) if len(revprops) > 1: args.append(revprops.items()) self.send_msg([literal("commit"), args]) self._recv_ack() raise NotImplementedError(self.get_commit_editor)
def stat(self, path, revision=-1): args = [path] if revision is None or revision == -1: args.append([revision]) else: args.append([]) self.send_msg([literal("stat"), args]) self._recv_ack() ret = self._unpack() if len(ret) == 0: return None return unmarshall_dirent(ret[0])
def location_segments(self, path, start_revision, end_revision, include_merged_revisions=False): args = [path] if start_revision is None or start_revision == -1: args.append([]) else: args.append([start_revision]) if end_revision is None or end_revision == -1: args.append([]) else: args.append([end_revision]) args.append(include_merged_revisions) self.send_msg([literal("get-location-segments"), args]) self._recv_ack() while True: msg = self.recv_msg() if msg == "done": break yield msg self._unpack()
def send_failure(self, *contents): self.send_msg([literal("failure"), list(contents)])
def send_mechs(self): self.send_success([literal(x) for x in MECHANISMS], "")
def send_greeting(self): self.send_success( MIN_VERSION, MAX_VERSION, [literal(x) for x in MECHANISMS], [literal(x) for x in CAPABILITIES])
def reparent(self, url): self.send_msg([literal("reparent"), [url]]) self._recv_ack() self._unpack() self.url = url