BAT Pack can now exclude files based on glob patterns

This commit is contained in:
Sybren A. Stüvel 2018-03-14 14:28:51 +01:00
parent 0e9de7753c
commit 8340df129d
3 changed files with 53 additions and 10 deletions

View File

@ -26,19 +26,21 @@ def add_parser(subparsers):
'directoy.') 'directoy.')
parser.add_argument('-n', '--noop', default=False, action='store_true', parser.add_argument('-n', '--noop', default=False, action='store_true',
help="Don't copy files, just show what would be done.") 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): def cli_pack(args):
bpath, ppath, tpath = paths_from_cli(args) bpath, ppath, tpath = paths_from_cli(args)
packer = create_packer(args, bpath, ppath, tpath) with create_packer(args, bpath, ppath, tpath) as packer:
packer.strategise() packer.strategise()
try: try:
packer.execute() packer.execute()
except blender_asset_tracer.pack.transfer.FileTransferError as ex: except blender_asset_tracer.pack.transfer.FileTransferError as ex:
log.error("%d files couldn't be copied, starting with %s", log.error("%d files couldn't be copied, starting with %s",
len(ex.files_remaining), ex.files_remaining[0]) len(ex.files_remaining), ex.files_remaining[0])
raise SystemExit(1) raise SystemExit(1)
def create_packer(args, bpath: pathlib.Path, ppath: pathlib.Path, 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:]) tpath = pathlib.Path(*tpath.parts[2:])
log.info('Uploading to S3-compatible storage %s at %s', endpoint, tpath) 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]: def paths_from_cli(args) -> typing.Tuple[pathlib.Path, pathlib.Path, pathlib.Path]:

View File

@ -62,6 +62,8 @@ class Packer:
self.target = target self.target = target
self.noop = noop self.noop = noop
self._exclude_globs = set() # type: typing.Set[str]
from blender_asset_tracer.cli import common from blender_asset_tracer.cli import common
self._shorten = functools.partial(common.shorten, self.project) self._shorten = functools.partial(common.shorten, self.project)
@ -89,6 +91,10 @@ class Packer:
def __exit__(self, exc_type, exc_val, exc_tb) -> None: def __exit__(self, exc_type, exc_val, exc_tb) -> None:
self.close() 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: def strategise(self) -> None:
"""Determine what to do with the assets. """Determine what to do with the assets.
@ -112,6 +118,10 @@ class Packer:
# blendfile thing, since different blendfiles can refer to it in # blendfile thing, since different blendfiles can refer to it in
# different ways (for example with relative and absolute paths). # different ways (for example with relative and absolute paths).
asset_path = usage.abspath 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(): if not asset_path.exists():
log.info('Missing file: %s', asset_path) log.info('Missing file: %s', asset_path)
self.missing_files.add(asset_path) self.missing_files.add(asset_path)

View File

@ -217,3 +217,25 @@ class PackTest(AbstractPackTest):
self.blendfiles / 'textures/Textures/Marble/marble_decoration-color.png'], self.blendfiles / 'textures/Textures/Marble/marble_decoration-color.png'],
sorted(packer.missing_files) 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)
)