Package: release.debian.org Severity: normal User: release.debian....@packages.debian.org Usertags: unblock
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Please unblock package pristine-lfs [ Reason ] Not knowing that pristine-lfs is considered a key package, I made changes upstream and uploaded a new release into Debian, fixing a few bugs and improving the exported API to make the future integration with git-buildpackage easier. [ Impact ] The direct impact in the event the unblock is not granted is low, since the new features aren’t used yet and the bugs have been previously worked around specifically in Debian bullseye. On the other hand, for the outlined reasons the impact on unblocking will also be very low. [ Tests ] - - There’s a test of tests running upstream on four Python releases (3.7, 3.8, 3.9 and 3.10-rc) and in Debian on the current Python release at build time; these tests cover all features but test them directly in Python - - The Debian package ships autopkgtests testing some of the basic features through the command-line interface. - - The upstream Ci runs mypy static type checks. [ Risks ] The changes are not trivial but OTOH not big and covered by tests; the overall test coverage has increased since the last upload, hence the risks of accepting this package into bullseye should be relatively low. [ Checklist ] [x] all changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in testing unblock pristine-lfs/20210404.0-1 -----BEGIN PGP SIGNATURE----- iHUEARYIAB0WIQSD3NF/RLIsyDZW7aHoRGtKyMdyYQUCYGsP6AAKCRDoRGtKyMdy Yc+rAQCsmONKT1dDAIwolvhF5uMJXtR9KiqIOyQi1DSosoJ1ZgEA+bf359mV6UDQ +g2N6APILtvME0Agpz62ZKDz4YqI6wo= =5H1H -----END PGP SIGNATURE-----
diff --git a/PKG-INFO b/PKG-INFO index 8db2f11..5b3e484 100644 --- a/PKG-INFO +++ b/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pristine-lfs -Version: 20210222.0 +Version: 20210404.0 Summary: a pristine-tar replacement that works with Git LFS Home-page: https://salsa.debian.org/pristine-lfs-team/pristine-lfs Author: Andrej Shadura diff --git a/debian/changelog b/debian/changelog index 9804ad5..1afd619 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +pristine-lfs (20210404.0-1) unstable; urgency=medium + + * New upstream release. + + -- Andrej Shadura <andrew.shad...@collabora.co.uk> Sun, 04 Apr 2021 22:15:42 +0200 + pristine-lfs (20210222.0-1) unstable; urgency=medium * New upstream release. diff --git a/pristine_lfs.egg-info/PKG-INFO b/pristine_lfs.egg-info/PKG-INFO index 8db2f11..5b3e484 100644 --- a/pristine_lfs.egg-info/PKG-INFO +++ b/pristine_lfs.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pristine-lfs -Version: 20210222.0 +Version: 20210404.0 Summary: a pristine-tar replacement that works with Git LFS Home-page: https://salsa.debian.org/pristine-lfs-team/pristine-lfs Author: Andrej Shadura diff --git a/pristine_lfs.egg-info/SOURCES.txt b/pristine_lfs.egg-info/SOURCES.txt index 70a9467..2f79c38 100644 --- a/pristine_lfs.egg-info/SOURCES.txt +++ b/pristine_lfs.egg-info/SOURCES.txt @@ -6,8 +6,10 @@ pristine-lfs.rst setup.cfg setup.py pristine_lfs/__init__.py +pristine_lfs/errors.py pristine_lfs/gitwrap.py pristine_lfs/gitwrap.pyi +pristine_lfs/log.py pristine_lfs/main.py pristine_lfs/util.py pristine_lfs.egg-info/PKG-INFO diff --git a/pristine_lfs.egg-info/requires.txt b/pristine_lfs.egg-info/requires.txt index b065e88..9a19637 100644 --- a/pristine_lfs.egg-info/requires.txt +++ b/pristine_lfs.egg-info/requires.txt @@ -1,2 +1,2 @@ python-debian -sh +sh>=1.14 diff --git a/pristine_lfs/__init__.py b/pristine_lfs/__init__.py index 6df221a..ded6987 100644 --- a/pristine_lfs/__init__.py +++ b/pristine_lfs/__init__.py @@ -1,5 +1,6 @@ from .main import ( # noqa: F401 do_commit, + do_commit_files, do_checkout, do_list, do_import, diff --git a/pristine_lfs/errors.py b/pristine_lfs/errors.py new file mode 100644 index 0000000..ca1db96 --- /dev/null +++ b/pristine_lfs/errors.py @@ -0,0 +1,67 @@ +# pristine-lfs +# +# errors for pristine-lfs +# +# Copyright (C) 2021 Collabora Ltd +# Copyright (C) 2021 Andrej Shadura <andrew.shad...@collabora.co.uk> +# +# SPDX-License-Identifier: GPL-2.0-or-later + +from __future__ import annotations + +from gettext import gettext as _ + +from sh import ErrorReturnCode as CommandFailed # noqa: F401 + + +class DifferentFilesExist(Exception): + files: list[str] + + def __init__(self, files: list[str]): + self.files = files + + def __str__(self): + return _("would overwrite files: {files}").format(files=', '.join(self.files)) + + +class UnsupportedHashAlgorithm(Exception): + algo: str + + def __init__(self, algo: str): + self.algo = algo + + def __str__(self): + return _("unsupported hash algorithm {algo}").format( + algo=self.algo, + ) + + +class GitError(Exception): + pass + + +class GitFileNotFound(GitError): + filename: str + branch: str + + def __init__(self, filename: str, branch: str): + self.filename = filename + self.branch = branch + + def __str__(self): + return _('{filename} not found on branch {branch}').format( + filename=self.filename, + branch=self.branch, + ) + + +class GitBranchNotFound(GitError): + branch: str + + def __init__(self, branch: str): + self.branch = branch + + def __str__(self): + return _('No branch {branch} found, not even among remote branches').format( + branch=self.branch, + ) diff --git a/pristine_lfs/gitwrap.py b/pristine_lfs/gitwrap.py index 0b0a83a..824988d 100644 --- a/pristine_lfs/gitwrap.py +++ b/pristine_lfs/gitwrap.py @@ -1,7 +1,7 @@ # Wrapper for Git and Git LFS # # Copyright (C) 2021 Collabora Ltd -# Andrej Shadura <andrew.shad...@collabora.co.uk> +# Copyright (C) 2021 Andrej Shadura <andrew.shad...@collabora.co.uk> # # SPDX-License-Identifier: GPL-2.0-or-later diff --git a/pristine_lfs/gitwrap.pyi b/pristine_lfs/gitwrap.pyi index 200b212..c760b45 100644 --- a/pristine_lfs/gitwrap.pyi +++ b/pristine_lfs/gitwrap.pyi @@ -2,7 +2,7 @@ # Extend as needed. # # Copyright (C) 2021 Collabora Ltd -# Andrej Shadura <andrew.shad...@collabora.co.uk> +# Copyright (C) 2021 Andrej Shadura <andrew.shad...@collabora.co.uk> from sh.contrib import git as sh_git diff --git a/pristine_lfs/log.py b/pristine_lfs/log.py new file mode 100644 index 0000000..a5b3cac --- /dev/null +++ b/pristine_lfs/log.py @@ -0,0 +1,13 @@ +# pristine-lfs +# +# logging +# +# Copyright (C) 2021 Collabora Ltd +# Copyright (C) 2021 Andrej Shadura <andrew.shad...@collabora.co.uk> +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import logging + + +logger = logging.getLogger("pristine-lfs") diff --git a/pristine_lfs/main.py b/pristine_lfs/main.py index 5cbaf66..921c312 100644 --- a/pristine_lfs/main.py +++ b/pristine_lfs/main.py @@ -3,7 +3,7 @@ # store pristine tarballs in Git LFS # # Copyright (C) 2019—2021 Collabora Ltd -# Andrej Shadura <andrew.shad...@collabora.co.uk> +# Copyright (C) 2019—2021 Andrej Shadura <andrew.shad...@collabora.co.uk> # # SPDX-License-Identifier: GPL-2.0-or-later @@ -18,6 +18,7 @@ from typing import ( IO, Iterable, Optional, + Sequence, Union ) @@ -25,9 +26,14 @@ import sh from debian import deb822 from debian.changelog import Changelog, Version +from .errors import ( + CommandFailed, + DifferentFilesExist, + GitError, + UnsupportedHashAlgorithm, +) +from .log import logger from .util import ( - Abort, - GitFileNotFound, check_branch, checkout_lfs_file, checkout_package, @@ -53,13 +59,29 @@ def do_commit(tarball: IO[bytes], branch: str, message: Optional[str] = None, fo commit_lfs_file(tarball, branch, message, overwrite=force_overwrite) -def do_checkout(branch: str, tarball: Optional[str] = None, outdir: Union[str, Path] = '.', full: bool = False, **kwargs): +def do_commit_files(tarballs: Sequence[IO[bytes]], branch: str, message: Optional[str] = None, + force_overwrite: bool = False, **kwargs): + """ + Commit open files to a branch using Git LFS. + Set force_overwrite to overwrite existing files with same names and different checksums. + Message may contain "%s" which gets replaced with a comma-separate list of the file committed. + """ + if check_branch(branch) is None: + if find_remote_branches(branch): + track_remote_branch(branch) + commit_lfs_files(tarballs, branch, message, overwrite=force_overwrite) + + +def do_checkout(branch: str, tarball: Optional[str] = None, outdir: Union[str, Path] = '.', full: bool = False, + package: Optional[str] = None, version: Union[str, Version, None] = None, **kwargs): """ Check out one or multiple files. If tarball is non-None: * file name only: tarball to check out to outdir. * path with to file: the location where to check out to If tarball is None: + * if package and version are specified, that version + is checked out * a tarball corresponding to the latest entry in debian/changelog is found and checked out @@ -74,10 +96,11 @@ def do_checkout(branch: str, tarball: Optional[str] = None, outdir: Union[str, P if path: outdir = path else: - changelog = Path("debian/changelog") - with changelog.open() as f: - ch = Changelog(f, max_blocks=1) - package, version = ch.package, ch.version + if not package or not version: + changelog = Path("debian/changelog") + with changelog.open() as f: + ch = Changelog(f, max_blocks=1) + package, version = ch.package, ch.version outdir = Path(outdir) outdir.mkdir(parents=True, exist_ok=True) @@ -86,24 +109,24 @@ def do_checkout(branch: str, tarball: Optional[str] = None, outdir: Union[str, P if tarball: dsc_file = tarball else: - fver = Version(ch.version) + fver = Version(version) fver.epoch = None dsc_file = f'{package}_{fver}.dsc' - logging.info(_("Checking out file {} in {}").format(dsc_file, outdir)) + logger.info(_("Checking out file {} in {}").format(dsc_file, outdir)) checkout_lfs_file(branch, dsc_file, outdir) if dsc_file.endswith('.dsc'): with (outdir / dsc_file).open('r') as dsc: d = deb822.Dsc(dsc) - package = d['Source'] + package = str(d['Source']) version = Version(d['Version']) files = [f["name"] for f in d["Files"]] checkout_package(package, version, branch, outdir, files) else: if tarball: - logging.info(_("Checking out file {} in {}").format(tarball, outdir)) + logger.info(_("Checking out file {} in {}").format(tarball, outdir)) checkout_lfs_file(branch, tarball, outdir) else: - checkout_package(package, version, branch, outdir) + checkout_package(str(package), Version(version), branch, outdir) def do_list(branch: str, **kwargs) -> Iterable[str]: @@ -116,7 +139,8 @@ def do_list(branch: str, **kwargs) -> Iterable[str]: yield f -def do_import(dsc: IO[str], branch: str, message: Optional[str] = None, force_overwrite: bool = False, full: bool = False, **kwargs): +def do_import(dsc: IO[str], branch: str, message: Optional[str] = None, force_overwrite: bool = False, + full: bool = False, **kwargs): """ Import all tarballs and detached signatures related to an open .dsc file. Set force_overwrite to overwrite an existing file with the same name and a different checksum. @@ -135,12 +159,13 @@ def do_import(dsc: IO[str], branch: str, message: Optional[str] = None, force_ov if find_remote_branches(branch): track_remote_branch(branch) - tarballs = [os.path.join(dsc_dir, f['name']) for f in d['Files'] if full or fnmatch(f['name'], tarball_glob) or fnmatch(f['name'], component_tarball_glob)] + tarballs = [os.path.join(dsc_dir, f['name']) for f in d['Files'] + if full or fnmatch(f['name'], tarball_glob) or fnmatch(f['name'], component_tarball_glob)] if full: tarballs += [dsc.name] if tarballs: - logging.info("Importing: %s" % " ".join(tarballs)) + logger.info("Importing: %s" % " ".join(tarballs)) commit_lfs_files([open(tarball, 'rb') for tarball in tarballs], branch, message, overwrite=force_overwrite) @@ -156,7 +181,10 @@ def do_verify(branch: str, tarball: Union[str, Path], **kwargs) -> bool: def main(*args): prog = os.path.basename(sys.argv[0]) - parser = argparse.ArgumentParser(description=_('store pristine tarballs in Git LFS'), prog=prog, exit_on_error=not args) + parser = argparse.ArgumentParser(description=_('store pristine tarballs in Git LFS'), prog=prog) + if args and hasattr(parser, 'exit_on_error'): + parser.exit_on_error = False + parser.add_argument('-v', '--verbose', action='count', help=_('be more verbose')) parser.add_argument('--debug', action='store_const', const=2, dest='verbose', help=_('be debuggingly verbose')) parser.set_defaults(verbose=0, func=lambda *x, **kw: parser.print_usage(file=sys.stderr)) @@ -173,10 +201,12 @@ def main(*args): # we have to do some trickery since argparse doesn’t support this syntax natively parser_checkout = subparsers.add_parser('checkout', help=_('checkout a tarball')) parser_checkout.add_argument('-b', '--branch', default='pristine-lfs', help=_('branch to store metadata on')) - parser_checkout.add_argument('--full', default=False, action='store_true', help=_('also check out all related files of the Debian package')) + parser_checkout.add_argument('--full', default=False, action='store_true', + help=_('also check out all related files of the Debian package')) parser_checkout.add_argument('-o', '--outdir', default='.', help=_('output directory for the tarball')) checkout_group = parser_checkout.add_mutually_exclusive_group(required=True) - checkout_group.add_argument('--auto', default=False, action='store_true', help=_('check out all tarballs required by the currently checked out Debian package')) + checkout_group.add_argument('--auto', default=False, action='store_true', + help=_('check out all tarballs required by the currently checked out Debian package')) checkout_group.add_argument('tarball', nargs='?', default=None, help=_('tarball to check out')) parser_checkout.set_defaults(func=do_checkout) @@ -187,7 +217,8 @@ def main(*args): parser_import = subparsers.add_parser('import-dsc', help=_('import tarballs and their signatures from a .dsc')) parser_import.add_argument('dsc', type=argparse.FileType('r'), help='.dsc file to use') parser_import.add_argument('--force-overwrite', action='store_true', help=_('overwrite already stored files')) - parser_import.add_argument('--full', default=False, action='store_true', help=_('also import all related files of the Debian package')) + parser_import.add_argument('--full', default=False, action='store_true', + help=_('also import all related files of the Debian package')) parser_import.add_argument('-m', '--message', default=None, help=_('commit message')) parser_import.add_argument('-b', '--branch', default='pristine-lfs', help=_('branch to store metadata on')) parser_import.set_defaults(func=do_import) @@ -211,7 +242,7 @@ def main(*args): print(item) elif isinstance(ret, bool): return 0 if ret else 1 - except sh.ErrorReturnCode as e: + except CommandFailed as e: print(_('Failed to run %s:') % e.full_cmd, file=sys.stderr) print(e.stderr.decode(sh.DEFAULT_ENCODING, "replace"), file=sys.stderr) return e.exit_code @@ -225,6 +256,6 @@ def main(*args): print(file=sys.stderr) print(_('about: Interrupted by user'), file=sys.stderr) return 1 - except (Abort, GitFileNotFound) as e: + except (DifferentFilesExist, GitError, UnsupportedHashAlgorithm) as e: print(_("abort: %s\n") % e, file=sys.stderr) return 1 diff --git a/pristine_lfs/util.py b/pristine_lfs/util.py index ba7f908..48b07ef 100644 --- a/pristine_lfs/util.py +++ b/pristine_lfs/util.py @@ -4,14 +4,13 @@ # This requires Git and git-lfs to be installed. # # Copyright (C) 2019—2021 Collabora Ltd -# Andrej Shadura <andrew.shad...@collabora.co.uk> +# Copyright (C) 2019—2021 Andrej Shadura <andrew.shad...@collabora.co.uk> # # SPDX-License-Identifier: GPL-2.0-or-later from __future__ import annotations import hashlib -import logging import os from contextlib import contextmanager from fnmatch import fnmatch, fnmatchcase @@ -22,7 +21,14 @@ from typing import IO, Any, Generator, Iterable, Mapping, Optional, Sequence, Tu import sh from debian.changelog import Version +from .errors import ( + DifferentFilesExist, + GitBranchNotFound, + GitFileNotFound, + UnsupportedHashAlgorithm, +) from .gitwrap import git +from .log import logger gitattributes = """*.tar.* filter=lfs diff=lfs merge=lfs -text @@ -133,22 +139,6 @@ def parse_git_attributes(s: str) -> Iterable[tuple[str, Mapping[str, AttributeVa default_gitattributes = list(parse_git_attributes(gitattributes)) -class Abort(Exception): - pass - - -class GitFileNotFound(Exception): - filename: str - branch: str - - def __init__(self, filename: str, branch: str): - self.filename = filename - self.branch = branch - - def __str__(self): - return _('%s not found on branch %s') % (self.filename, self.branch) - - def check_branch(name: str) -> Optional[str]: """ Check a branch exists, return the hash it points at, if it does. @@ -187,9 +177,9 @@ def find_remote_branches(name: str) -> list[tuple[str, str]]: def preferred_remote_branch(remote_branches: list[tuple[str, str]]) -> tuple[str, str]: - logging.debug("Remote branches: %r", remote_branches) + logger.debug("Remote branches: %r", remote_branches) current_remote = branch_remote(git_head()) - logging.debug("Current remote: %r", current_remote) + logger.debug("Current remote: %r", current_remote) remote_branches = [ (commit, ref) for (commit, ref) in remote_branches if current_remote and ref.startswith('refs/remotes/' + current_remote) @@ -211,7 +201,7 @@ def find_branch(branch: str) -> str: if remote_branches: commit, branch = preferred_remote_branch(remote_branches) else: - raise Abort(_('No branch {branch} found, not even among remote branches').format(branch=branch)) + raise GitBranchNotFound(branch) return branch @@ -307,7 +297,7 @@ def commit_lfs_files(ios: Sequence[IO[bytes]], branch: str, template: str = None hook_path.write_text(pre_push_hook) hook_path.chmod(0o755) except IOError as e: - logging.warning(_('Failed to set up pre-push hook: %s') % e.strerror) + logger.warning(_('Failed to set up pre-push hook: %s') % e.strerror) with open_index("pristine-lfs") as index: # make sure we include all previously committed files @@ -328,12 +318,12 @@ def commit_lfs_files(ios: Sequence[IO[bytes]], branch: str, template: str = None if check_branch(branch) is not None: diff = git('diff-index', '--cached', branch, index=index).strip().splitlines() if not diff: - logging.info(_("Nothing to commit")) + logger.info(_("Nothing to commit")) return parsed_diff = [parse_diff_entry(d) for d in diff] overwritten = [d['srcname'] for d in parsed_diff if d['srchash'] != ('0' * 40) and d['srcname'] != '.gitattributes'] if any(overwritten) and not overwrite: - raise Abort(_('would overwrite files: %s') % ', '.join(overwritten)) + raise DifferentFilesExist(overwritten) if not template: template = "pristine-lfs data for %s" @@ -399,7 +389,7 @@ def verify_lfs_file(branch: str, tarball: Path) -> bool: oid = parsed_metadata['oid'] algo, hashsum = oid.split(':', 1) if algo not in supported_lfs_hashsums: - raise Abort(_("unsupported hash algorithm %s, cannot verify") % algo) + raise UnsupportedHashAlgorithm(algo) h = getattr(hashlib, algo)() with open(tarball, mode='rb') as f: @@ -410,9 +400,9 @@ def verify_lfs_file(branch: str, tarball: Path) -> bool: h.update(chunk) calc_hashsum = h.hexdigest() if hashsum == calc_hashsum: - logging.info(f"{algo} hash for the tarball: {hashsum}, matches the stored one") + logger.info(f"{algo} hash for the tarball: {hashsum}, matches the stored one") else: - logging.warning(_("%(tarball)s does not match stored hash (expected %(stored_hash)s, got %(tarball_hash)s)") % { + logger.warning(_("%(tarball)s does not match stored hash (expected %(stored_hash)s, got %(tarball_hash)s)") % { 'tarball': filename, 'stored_hash': hashsum, 'tarball_hash': calc_hashsum, @@ -420,8 +410,12 @@ def verify_lfs_file(branch: str, tarball: Path) -> bool: return hashsum == calc_hashsum -def checkout_package(package: str, version: Version, branch: str, outdir: Union[str, Path], requested: Optional[Sequence[str]] = None): - logging.info(_("Checking out files for {package} version {version} to {outdir}:").format(package=package, version=version, outdir=outdir)) +def checkout_package(package: str, version: Version, branch: str, outdir: Union[str, Path], + requested: Optional[Sequence[str]] = None): + logger.info(_("Checking out files for {package} version {version} to {outdir}:").format( + package=package, + version=version, outdir=outdir + )) tarball_glob = f'{package}_{version.upstream_version}.orig.tar.*' component_tarball_glob = f'{package}_{version.upstream_version}.orig-*.tar.*' @@ -433,9 +427,9 @@ def checkout_package(package: str, version: Version, branch: str, outdir: Union[ tarballs = [f for f in files if fnmatch(f, tarball_glob) or fnmatch(f, component_tarball_glob)] for f in tarballs: - logging.info(" ... {}".format(f)) + logger.info(" ... {}".format(f)) checkout_lfs_file(branch, f, outdir) - logging.info(_("Done.")) + logger.info(_("Done.")) def parse_pointer(pointer: IO[str]) -> Iterable[tuple[str, str]]: diff --git a/setup.cfg b/setup.cfg index 04de573..16535af 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pristine-lfs -version = 20210222.0 +version = 20210404.0 author = Andrej Shadura author_email = andrew.shad...@collabora.co.uk url = https://salsa.debian.org/pristine-lfs-team/pristine-lfs @@ -28,7 +28,7 @@ packages = find: setup_requires = docutils >= 0.12 install_requires = - sh + sh >= 1.14 python-debian include_package_data = True tests_require = @@ -43,9 +43,11 @@ pristine_lfs = stubs/* [mypy] allow_redefinition = True +junit_xml = mypy.xml [tool:pytest] -addopts = --doctest-modules +addopts = --doctest-modules --junit-xml=test-results.xml +junit_family = xunit2 doctest_optionflags = NORMALIZE_WHITESPACE markers = smoke @@ -54,7 +56,7 @@ markers = doctests = yes max-line-length = 130 exclude = .git,build,__pycache__,setup.py -ignore = E121,E123,E126,E133,E226,E241,E242,E704,E501,E301,E261,E127,E128,W391,W503,W504 +ignore = E121,E123,E126,E133,E226,E241,E242,E704,E261,E127,E128,W503,W504 [isort] multi_line_output = 3 @@ -64,6 +66,9 @@ line_length = 130 reverse_relative = true default_section = THIRDPARTY +[pylint.FORMAT] +max-line-length = 130 + [egg_info] tag_build = tag_date = 0 diff --git a/tests/test_checkout.py b/tests/test_checkout.py index f3c289a..9582527 100644 --- a/tests/test_checkout.py +++ b/tests/test_checkout.py @@ -1,4 +1,5 @@ from pristine_lfs import do_checkout +from pristine_lfs.util import Version def test_pristine_lfs_simple_checkout(fake_pristine_lfs): @@ -16,15 +17,33 @@ def test_pristine_lfs_auto_checkout(test_git_repo): outdir = repo / 'tmp-explicit' do_checkout('pristine-lfs', tarball=tarball.name, outdir=outdir) - assert len(list(outdir.glob('**'))) == 1, list(outdir.glob('**')) + assert len(list(outdir.glob('*'))) == 1, list(outdir.glob('*')) assert (outdir / tarball.name).is_file() assert (outdir / tarball.name).stat().st_size == size outdir = repo / 'tmp-auto' do_checkout('pristine-lfs', tarball=None, outdir=outdir) - assert len(list(outdir.glob('**'))) == 1, list(outdir.glob('**')) + assert len(list(outdir.glob('*'))) == 1, list(outdir.glob('*')) assert (outdir / tarball.name).is_file(), 'Extracted tarball not found' assert (outdir / tarball.name).stat().st_size == size, 'Extracted tarball of a wrong size' + outdir = repo / 'tmp-empty' + + do_checkout('pristine-lfs', package='true', version='1', outdir=outdir) + assert len(list(outdir.glob('*'))) == 0, list(outdir.glob('*')) + assert not (outdir / tarball.name).is_file(), 'Found a tarball which should not be there' + + do_checkout('pristine-lfs', package='true', version=Version('1'), outdir=outdir) + assert len(list(outdir.glob('*'))) == 0, list(outdir.glob('*')) + assert not (outdir / tarball.name).is_file(), 'Found a tarball which should not be there' + do_checkout('pristine-lfs', package='true', version='0', outdir=outdir) + assert len(list(outdir.glob('*'))) == 1, list(outdir.glob('*')) + assert (outdir / tarball.name).is_file(), 'Extracted tarball not found' + + outdir = repo / 'tmp-empty-2' + + do_checkout('pristine-lfs', package='true', version='0', outdir=outdir) + assert len(list(outdir.glob('*'))) == 1, list(outdir.glob('*')) + assert (outdir / tarball.name).is_file(), 'Extracted tarball not found' diff --git a/tests/test_commit.py b/tests/test_commit.py index c578d86..207b662 100644 --- a/tests/test_commit.py +++ b/tests/test_commit.py @@ -1,8 +1,10 @@ from textwrap import dedent +import pytest from sh.contrib import git from pristine_lfs import do_commit +from pristine_lfs.errors import DifferentFilesExist def test_pristine_lfs_commit(fake_tarball): @@ -24,3 +26,13 @@ def test_pristine_lfs_commit(fake_tarball): stored = repo / '.git' / 'lfs' / 'objects' / sha[:2] / sha[2:4] / sha assert stored.is_file(), 'Object has not been stored by LFS' + + +def test_pristine_lfs_commit_overwrite(fake_tarball): + repo, tarball, size, sha = fake_tarball + + do_commit(tarball.open('rb'), branch='pristine-lfs') + tarball.write_text('Text') + + with pytest.raises(DifferentFilesExist): + do_commit(tarball.open('rb'), branch='pristine-lfs', message='blip %s %s %s') diff --git a/tests/test_import_dsc.py b/tests/test_import_dsc.py index e5e5a4c..df94fda 100644 --- a/tests/test_import_dsc.py +++ b/tests/test_import_dsc.py @@ -40,4 +40,3 @@ def test_pristine_lfs_import_dsc(fake_tarball): ret = list(do_list(branch='pristine-lfs-source')) assert ['true_0.dsc', 'true_0.orig.tar.gz'] == ret -