Moved packer code into separate class, in preparation for smarter behaviour

This commit is contained in:
Sybren A. Stüvel 2018-03-06 11:58:38 +01:00
parent 92f91b42cf
commit 433ad8f16a
2 changed files with 71 additions and 37 deletions

View File

@ -5,7 +5,7 @@ import pathlib
import shutil import shutil
import sys import sys
from blender_asset_tracer import tracer from blender_asset_tracer import tracer, pack
from . import common from . import common
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -31,41 +31,9 @@ def add_parser(subparsers):
def cli_pack(args): def cli_pack(args):
bpath, ppath, tpath = paths_from_cli(args) bpath, ppath, tpath = paths_from_cli(args)
if args.noop: packer = pack.Packer(bpath, ppath, tpath, args.noop)
log.warning('Running in no-op mode, only showing what will be done.') packer.investigate()
packer.pack()
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)
def paths_from_cli(args) -> (pathlib.Path, pathlib.Path, pathlib.Path): 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 ppath = bpath.absolute().parent
log.warning('No project path given, using %s', ppath) log.warning('No project path given, using %s', ppath)
else: else:
ppath = args.project ppath = args.project.absolute()
if not ppath.exists(): if not ppath.exists():
log.critical('Project directory %s does not exist', ppath) log.critical('Project directory %s does not exist', ppath)

View File

@ -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))