From 8340df129d33cab059013042d8b5e9a1999a113b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Wed, 14 Mar 2018 14:28:51 +0100 Subject: [PATCH] BAT Pack can now exclude files based on glob patterns --- blender_asset_tracer/cli/pack.py | 31 ++++++++++++++++++--------- blender_asset_tracer/pack/__init__.py | 10 +++++++++ tests/test_pack.py | 22 +++++++++++++++++++ 3 files changed, 53 insertions(+), 10 deletions(-) diff --git a/blender_asset_tracer/cli/pack.py b/blender_asset_tracer/cli/pack.py index cfc96e7..dd36314 100644 --- a/blender_asset_tracer/cli/pack.py +++ b/blender_asset_tracer/cli/pack.py @@ -26,19 +26,21 @@ def add_parser(subparsers): 'directoy.') parser.add_argument('-n', '--noop', default=False, action='store_true', help="Don't copy files, just show what would be done.") + parser.add_argument('-e', '--exclude', nargs='*', default='', + help="Space-separated list of glob patterns (like '*.abc') to exclude.") def cli_pack(args): bpath, ppath, tpath = paths_from_cli(args) - packer = create_packer(args, bpath, ppath, tpath) - packer.strategise() - try: - packer.execute() - except blender_asset_tracer.pack.transfer.FileTransferError as ex: - log.error("%d files couldn't be copied, starting with %s", - len(ex.files_remaining), ex.files_remaining[0]) - raise SystemExit(1) + with create_packer(args, bpath, ppath, tpath) as packer: + packer.strategise() + try: + packer.execute() + except blender_asset_tracer.pack.transfer.FileTransferError as ex: + log.error("%d files couldn't be copied, starting with %s", + len(ex.files_remaining), ex.files_remaining[0]) + raise SystemExit(1) def create_packer(args, bpath: pathlib.Path, ppath: pathlib.Path, @@ -55,9 +57,18 @@ def create_packer(args, bpath: pathlib.Path, ppath: pathlib.Path, tpath = pathlib.Path(*tpath.parts[2:]) log.info('Uploading to S3-compatible storage %s at %s', endpoint, tpath) - return s3.S3Packer(bpath, ppath, tpath, endpoint=endpoint) + packer = s3.S3Packer(bpath, ppath, tpath, endpoint=endpoint) # type: pack.Packer + else: + packer = pack.Packer(bpath, ppath, tpath, args.noop) - return pack.Packer(bpath, ppath, tpath, args.noop) + if args.exclude: + # args.exclude is a list, due to nargs='*', so we have to split and flatten. + globs = [glob + for globs in args.exclude + for glob in globs.split()] + log.info('Excluding: %s', ', '.join(repr(g) for g in globs)) + packer.exclude(*globs) + return packer def paths_from_cli(args) -> typing.Tuple[pathlib.Path, pathlib.Path, pathlib.Path]: diff --git a/blender_asset_tracer/pack/__init__.py b/blender_asset_tracer/pack/__init__.py index 77d45e7..cc3f288 100644 --- a/blender_asset_tracer/pack/__init__.py +++ b/blender_asset_tracer/pack/__init__.py @@ -62,6 +62,8 @@ class Packer: self.target = target self.noop = noop + self._exclude_globs = set() # type: typing.Set[str] + from blender_asset_tracer.cli import common self._shorten = functools.partial(common.shorten, self.project) @@ -89,6 +91,10 @@ class Packer: def __exit__(self, exc_type, exc_val, exc_tb) -> None: self.close() + def exclude(self, *globs: str): + """Register glob-compatible patterns of files that should be ignored.""" + self._exclude_globs.update(globs) + def strategise(self) -> None: """Determine what to do with the assets. @@ -112,6 +118,10 @@ class Packer: # blendfile thing, since different blendfiles can refer to it in # different ways (for example with relative and absolute paths). asset_path = usage.abspath + if any(asset_path.match(glob) for glob in self._exclude_globs): + log.info('Excluding file: %s', asset_path) + continue + if not asset_path.exists(): log.info('Missing file: %s', asset_path) self.missing_files.add(asset_path) diff --git a/tests/test_pack.py b/tests/test_pack.py index 02b78ad..a24be52 100644 --- a/tests/test_pack.py +++ b/tests/test_pack.py @@ -217,3 +217,25 @@ class PackTest(AbstractPackTest): self.blendfiles / 'textures/Textures/Marble/marble_decoration-color.png'], sorted(packer.missing_files) ) + + def test_exclude_filter(self): + # Files shouldn't be reported missing if they should be ignored. + infile = self.blendfiles / 'image_sequencer.blend' + with pack.Packer(infile, self.blendfiles, self.tpath) as packer: + packer.exclude('*.png', '*.nonsense') + packer.strategise() + packer.execute() + + self.assertFalse((self.tpath / 'imgseq').exists()) + + def test_exclude_filter_missing_files(self): + # Files shouldn't be reported missing if they should be ignored. + infile = self.blendfiles / 'missing_textures.blend' + with pack.Packer(infile, self.blendfiles, self.tpath) as packer: + packer.exclude('*.png') + packer.strategise() + + self.assertEqual( + [self.blendfiles / 'textures/HDRI/Myanmar/Golden Palace 2, Old Bagan-1k.exr'], + list(packer.missing_files) + )