def o4_seed_from(seed_dir, seed_fstat, op): """ For each target fstat on stdin, copy the matching file from the seed directory if 1) the seed fstat agrees, or 2) if no fstat, the checksum agrees. Output the fstat entries that were not copied. """ def no_uchg(*fnames): check_call(['chflags', 'nouchg'] + [fname for fname in fnames if os.path.exists(fname)]) def update_target(src, dest, fsop): try: try: os.makedirs(os.path.dirname(dest), exist_ok=True) fsop(src, dest) except IOError as e: if e.errno == EPERM and sys.platform == 'darwin': no_uchg(src, dest) fsop(src, dest) else: raise except IOError as e: print(f'# ERROR MOVING {src}: {e!r}') fsop = shutil.move if op == 'move' else shutil.copy2 seed_checksum = None if seed_fstat: seed_checksum = { f[F_PATH]: f[F_CHECKSUM] for f in fstat_from_csv(seed_fstat, fstat_split) if f } target_dir = os.getcwd() with chdir(seed_dir): for line in sys.stdin: if line.startswith('#o4pass'): print(line, end='') continue f = fstat_split(line) if not f: continue if f[F_CHECKSUM]: dest = os.path.join(target_dir, f[F_PATH]) if os.path.lexists(dest): try: os.unlink(dest) except IOError as e: if e.errno == EPERM and sys.platform == 'darwin': no_uchg(dest) os.unlink(dest) else: raise if seed_fstat: checksum = seed_checksum.get(f[F_PATH]) else: checksum = Pyforce.checksum(f[F_PATH], f[F_FILE_SIZE]) if f[F_FILE_SIZE].endswith( 'symlink') or checksum == f[F_CHECKSUM]: update_target(f[F_PATH], dest, fsop) print(line, end='') # line already ends with '\n'
def f_checksum(row): if os.path.lexists(row[F_PATH]): if not row[F_CHECKSUM]: # File is deleted if os.path.isdir(row[F_PATH]): return True elif row[F_FILE_SIZE].endswith('symlink') or Pyforce.checksum( row[F_PATH], row[F_FILE_SIZE]) == row[F_CHECKSUM]: return True else: if not row[F_CHECKSUM]: return True