From 433ad8f16a1c83ca791bc7b2574ff6a9529252fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 6 Mar 2018 11:58:38 +0100 Subject: [PATCH] Moved packer code into separate class, in preparation for smarter behaviour --- blender_asset_tracer/cli/pack.py | 42 ++--------------- blender_asset_tracer/pack/__init__.py | 66 +++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 37 deletions(-) create mode 100644 blender_asset_tracer/pack/__init__.py diff --git a/blender_asset_tracer/cli/pack.py b/blender_asset_tracer/cli/pack.py index 80fd778..38c9fda 100644 --- a/blender_asset_tracer/cli/pack.py +++ b/blender_asset_tracer/cli/pack.py @@ -5,7 +5,7 @@ import pathlib import shutil import sys -from blender_asset_tracer import tracer +from blender_asset_tracer import tracer, pack from . import common log = logging.getLogger(__name__) @@ -31,41 +31,9 @@ def add_parser(subparsers): def cli_pack(args): bpath, ppath, tpath = paths_from_cli(args) - if args.noop: - log.warning('Running in no-op mode, only showing what will be done.') - - shorten = functools.partial(common.shorten, ppath) - already_copied = set() - for usage in tracer.deps(bpath): - if usage.asset_path.is_absolute(): - raise NotImplementedError('Sorry, cannot handle absolute paths yet: %s' % usage) - - for assetpath in usage.files(): - try: - assetpath = assetpath.resolve() - except FileNotFoundError: - log.error('Dependency %s does not exist', assetpath) - - if assetpath in already_copied: - log.debug('Already copied %s', assetpath) - continue - already_copied.add(assetpath) - - relpath = shorten(assetpath) - if relpath.is_absolute(): - raise NotImplementedError('Sorry, cannot handle absolute paths yet: %s in %s' - % (usage, assetpath)) - - full_target = tpath / relpath - full_target.parent.mkdir(parents=True, exist_ok=True) - if args.noop: - print('%s → %s' % (assetpath, full_target)) - else: - print(relpath) - # TODO(Sybren): when we target Py 3.6+, remove the str() calls. - shutil.copyfile(str(assetpath), str(full_target)) - - log.info('Copied %d files to %s', len(already_copied), tpath) + packer = pack.Packer(bpath, ppath, tpath, args.noop) + packer.investigate() + packer.pack() def paths_from_cli(args) -> (pathlib.Path, pathlib.Path, pathlib.Path): @@ -87,7 +55,7 @@ def paths_from_cli(args) -> (pathlib.Path, pathlib.Path, pathlib.Path): ppath = bpath.absolute().parent log.warning('No project path given, using %s', ppath) else: - ppath = args.project + ppath = args.project.absolute() if not ppath.exists(): log.critical('Project directory %s does not exist', ppath) diff --git a/blender_asset_tracer/pack/__init__.py b/blender_asset_tracer/pack/__init__.py new file mode 100644 index 0000000..67a941a --- /dev/null +++ b/blender_asset_tracer/pack/__init__.py @@ -0,0 +1,66 @@ +import functools +import logging +import pathlib +import shutil + +from blender_asset_tracer import tracer +from blender_asset_tracer.cli import common + +log = logging.getLogger(__name__) + + +class Packer: + def __init__(self, + blendfile: pathlib.Path, + project: pathlib.Path, + target: pathlib.Path, + noop: bool): + self.blendfile = blendfile + self.project = project + self.target = target + self.noop = noop + + self._already_copied = set() + self._shorten = functools.partial(common.shorten, self.project) + + if noop: + log.warning('Running in no-op mode, only showing what will be done.') + + def investigate(self): + pass + + def pack(self): + for usage in tracer.deps(self.blendfile): + if usage.asset_path.is_absolute(): + raise NotImplementedError('Sorry, cannot handle absolute paths yet: %s' % usage) + + for assetpath in usage.files(): + self._copy_to_target(assetpath) + + log.info('Copied %d files to %s', len(self._already_copied), self.target) + + def _copy_to_target(self, assetpath: pathlib.Path): + try: + assetpath = assetpath.resolve() + except FileNotFoundError: + log.error('Dependency %s does not exist', assetpath) + + if assetpath in self._already_copied: + log.debug('Already copied %s', assetpath) + return + self._already_copied.add(assetpath) + + relpath = self._shorten(assetpath) + if relpath.is_absolute(): + raise NotImplementedError( + 'Sorry, cannot handle paths outside project directory yet: %s is not in %s' + % (relpath, self.project)) + + full_target = self.target / relpath + full_target.parent.mkdir(parents=True, exist_ok=True) + if self.noop: + print('%s → %s' % (assetpath, full_target)) + else: + print(relpath) + # TODO(Sybren): when we target Py 3.6+, remove the str() calls. + shutil.copyfile(str(assetpath), str(full_target))