def check(args): if args.stdin: if args.files: raise ArgError("can't accept both, --stdin and the files argument") files = [Path(l.strip()) for l in sys.stdin] else: if args.files: files = args.files else: files = None with Archive().open(args.archive) as archive: if files is None: files = [archive.basedir] metadata = {Path(md) for md in archive.manifest.metadata} FileInfo.Checksums = archive.manifest.checksums file_iter = FileInfo.iterpaths(files, set()) skip = None while True: try: fi = file_iter.send(skip) except StopIteration: break skip = False entry = archive.manifest.find(args.prefix / fi.path) if (args.prefix / fi.path in metadata or entry and _matches(args.prefix, fi, entry)): if args.present and not fi.is_dir(): print(fi.path) else: if not args.present: print(fi.path) if fi.is_dir(): skip = True return 0
def test_create_fileinfos_generator(test_dir, monkeypatch): """Create the archive from FileInfo.iterpaths() which returns a generator. """ monkeypatch.chdir(test_dir) fileinfos = FileInfo.iterpaths([Path("base")], set()) archive_path = Path("archive-fi-generator.tar") Archive().create(archive_path, "", fileinfos=fileinfos) with Archive().open(archive_path) as archive: check_manifest(archive.manifest, testdata) archive.verify()
def test_create_fileinfos_list(test_dir, monkeypatch): """Create the archive from a list of FileInfo objects. """ monkeypatch.chdir(test_dir) fileinfos = list(FileInfo.iterpaths([Path("base")], set())) archive_path = Path("archive-fi-list.tar") Archive().create(archive_path, "", fileinfos=fileinfos) with Archive().open(archive_path) as archive: check_manifest(archive.manifest, testdata) archive.verify()
def test_create_fileinfos_subset(test_dir, monkeypatch): """Do not include the content of a directory. This test verifies that creating an archive from fileinfos does not implicitly descend subdirectories. """ monkeypatch.chdir(test_dir) excludes = [Path("base", "data", "rnd.dat")] fileinfos = FileInfo.iterpaths([Path("base")], set(excludes)) data = sub_testdata(testdata, excludes[0]) archive_path = Path("archive-fi-subset.tar") Archive().create(archive_path, "", fileinfos=fileinfos) with Archive().open(archive_path) as archive: check_manifest(archive.manifest, data) archive.verify()
def test_manifest_from_fileinfos(test_dir, monkeypatch): """Create a manifest providing an iterable of fileinfos. """ monkeypatch.chdir(test_dir) fileinfos = FileInfo.iterpaths([Path("base")], set()) manifest = Manifest(fileinfos=fileinfos) head = manifest.head assert set(head.keys()) == { "Checksums", "Date", "Generator", "Metadata", "Version" } assert manifest.version == Manifest.Version assert isinstance(manifest.date, datetime.datetime) assert manifest.checksums == tuple(FileInfo.Checksums) assert manifest.tags == () check_manifest(manifest, testdata)
def test_create_fileinfos_missing_checksum(test_dir, testname, monkeypatch): """When an archive is created from precompiled fileinfos, they must already contain suitable checksums. """ monkeypatch.chdir(test_dir) name = archive_name(tags=[testname]) with monkeypatch.context() as m: m.setattr(FileInfo, "Checksums", ['md5']) fileinfos = list(FileInfo.iterpaths([Path("base")], set())) # Checksums are calculated lazily, we must explicitely access # the attribute while monkeypatching FileInfo.Checksums is # active. for fi in fileinfos: if fi.is_file(): assert set(fi.checksum.keys()) == {'md5'} with pytest.raises(ArchiveCreateError) as err: Archive().create(Path(name), "", fileinfos=fileinfos) assert "Missing checksum" in str(err.value)
def get_fileinfos(base): fileinfos = FileInfo.iterpaths([base], set()) return sorted(fileinfos, key=lambda fi: fi.path)