def _assertDirInfoEqual(self, dir_info1, dir_info2): for fi1, fi2 in util.merge_two_iterators( dir_info1.flat_file_info_list(), dir_info2.flat_file_info_list(), key_func=lambda x: x.path_for_sorting()): self.assertIsNotNone(fi1) self.assertIsNotNone(fi2) self.assertEquals(fi1.path, fi2.path) self.assertEquals(fi1.is_dir, fi2.is_dir) self.assertFalse(fi1.is_modified(fi2))
def merge(dir_changes1, dir_changes2, parent_dir_changes_new1=None, parent_dir_changes_old1=None, parent_dir_changes_new2=None, parent_dir_changes_old2=None, parent_dir_changes_conflict=None): base_dir = ( dir_changes1.base_dir() if dir_changes1 else dir_changes2.base_dir()) dc_new1 = change_entry.DirChanges(base_dir, change_entry.CONTENT_STATUS_UNSPECIFIED, parent_dir_changes=parent_dir_changes_new1) dc_old1 = change_entry.DirChanges(base_dir, change_entry.CONTENT_STATUS_UNSPECIFIED, parent_dir_changes=parent_dir_changes_old1) dc_new2 = change_entry.DirChanges(base_dir, change_entry.CONTENT_STATUS_UNSPECIFIED, parent_dir_changes=parent_dir_changes_new2) dc_old2 = change_entry.DirChanges(base_dir, change_entry.CONTENT_STATUS_UNSPECIFIED, parent_dir_changes=parent_dir_changes_old2) dc_conflict = change_entry.DirChanges( base_dir, change_entry.CONTENT_STATUS_UNSPECIFIED, parent_dir_changes=parent_dir_changes_conflict) for c1, c2 in util.merge_two_iterators( iter(dir_changes1.changes() if dir_changes1 else []), iter(dir_changes2.changes() if dir_changes2 else []), key_func=lambda x: util.path_for_sorting(x.path)): if _is_file_change(c1) and _is_file_change(c2): _merge_both_files(c1, c2, dc_new1, dc_old1, dc_new2, dc_old2, dc_conflict) else: _merge_both_dirs(c1, c2, dir_changes1.dir_changes(c1.path) if c1 else None, dir_changes2.dir_changes(c2.path) if c2 else None, dc_new1, dc_old1, dc_new2, dc_old2, dc_conflict) return dc_new1, dc_old1, dc_new2, dc_old2, dc_conflict
def get_dir_changes(new_dir_info, old_dir_info, parent_dir_changes=None, root_dir=None, tmp_dir=None, verbose=False): # TODO: add permission change status top_dir_delete_change_path = None base_dir = (new_dir_info.base_dir() if new_dir_info else old_dir_info.base_dir()) cur_dir_changes = DirChanges(base_dir, CONTENT_STATUS_NO_CHANGE, parent_dir_changes=parent_dir_changes) for e_new_info, e_old_info in util.merge_two_iterators( iter(new_dir_info.file_info_list() if new_dir_info else []), iter(old_dir_info.file_info_list() if old_dir_info else []), key_func=lambda x: x.path_for_sorting()): dir_status = CONTENT_STATUS_NO_CHANGE tmp_file = None dir_changes = None if e_new_info and e_old_info: if e_new_info.is_dir and e_old_info.is_dir: dir_changes = get_dir_changes(new_dir_info.dir_info(e_new_info.path), old_dir_info.dir_info(e_old_info.path), parent_dir_changes=cur_dir_changes, root_dir=root_dir, tmp_dir=tmp_dir, verbose=verbose) if dir_changes.dir_status() == CONTENT_STATUS_NO_CHANGE: content_status = CONTENT_STATUS_NO_CHANGE else: content_status = CONTENT_STATUS_MODIFIED dir_status = dir_changes.dir_status() elif e_new_info.is_dir and not e_old_info.is_dir: if verbose: print '%s: file to dir' % e_new_info.path dir_changes = get_dir_changes(new_dir_info.dir_info(e_new_info.path), None, parent_dir_changes=cur_dir_changes, root_dir=root_dir, tmp_dir=tmp_dir, verbose=verbose) content_status = CONTENT_STATUS_TO_DIR dir_status = dir_changes.dir_status() elif not e_new_info.is_dir and e_old_info.is_dir: if verbose: print '%s: dir to file' % e_new_info.path dir_changes = get_dir_changes(None, old_dir_info.dir_info(e_old_info.path), parent_dir_changes=cur_dir_changes, root_dir=root_dir, tmp_dir=tmp_dir, verbose=verbose) content_status = CONTENT_STATUS_TO_FILE dir_status = dir_changes.dir_status() if root_dir and tmp_dir: tmp_file = _copy_to_tmp_dir(root_dir, e_new_info.path, tmp_dir) else: if e_new_info.is_modified(e_old_info): if verbose: print '%s: file modified' % e_new_info.path content_status = CONTENT_STATUS_MODIFIED if root_dir and tmp_dir: tmp_file = _copy_to_tmp_dir(root_dir, e_new_info.path, tmp_dir) else: content_status = CONTENT_STATUS_NO_CHANGE path = e_new_info.path if (not e_new_info.compressed_file_info and e_old_info.compressed_file_info and content_status == CONTENT_STATUS_NO_CHANGE): e_new_info.compressed_file_info = e_old_info.compressed_file_info if (not e_new_info.original_file_info and e_old_info.original_file_info and content_status == CONTENT_STATUS_NO_CHANGE): e_new_info.original_file_info = e_old_info.original_file_info if tmp_file: e_new_info = file_info.copy_with_tmp_file(e_new_info, tmp_file, tmp_dir) change = ChangeEntry( e_new_info.path, e_new_info, e_old_info, content_status, dir_changes=dir_changes, parent_dir_changes=cur_dir_changes) elif e_new_info and not e_old_info: path = e_new_info.path if e_new_info.is_dir: if verbose: print '%s: new dir' % e_new_info.path dir_changes = get_dir_changes(new_dir_info.dir_info(e_new_info.path), None, parent_dir_changes=cur_dir_changes, root_dir=root_dir, tmp_dir=tmp_dir, verbose=verbose) dir_status = dir_changes.dir_status() else: if verbose: print '%s: new file' % e_new_info.path if root_dir and tmp_dir: tmp_file = _copy_to_tmp_dir(root_dir, e_new_info.path, tmp_dir) if tmp_file: e_new_info = file_info.copy_with_tmp_file(e_new_info, tmp_file, tmp_dir) change = ChangeEntry( e_new_info.path, e_new_info, None, CONTENT_STATUS_NEW, dir_changes=dir_changes, parent_dir_changes=cur_dir_changes) elif not e_new_info and e_old_info: path = e_old_info.path if e_old_info.is_dir: if verbose: print '%s: dir deleted' % e_old_info.path dir_changes = get_dir_changes(None, old_dir_info.dir_info(e_old_info.path), parent_dir_changes=cur_dir_changes, root_dir=root_dir, tmp_dir=tmp_dir, verbose=verbose) dir_status = dir_changes.dir_status() else: if verbose: print '%s: file deleted' % e_old_info.path change = ChangeEntry( e_old_info.path, None, e_old_info, CONTENT_STATUS_DELETED, dir_changes=dir_changes, parent_dir_changes=cur_dir_changes) cur_dir_changes.add_change(change) return cur_dir_changes