diff --git a/blender_asset_tracer/cli/pack.py b/blender_asset_tracer/cli/pack.py index ce7bbe5..894627f 100644 --- a/blender_asset_tracer/cli/pack.py +++ b/blender_asset_tracer/cli/pack.py @@ -58,6 +58,9 @@ def add_parser(subparsers): 'packing into a directory (contrary to ZIP file or S3 upload). ' 'Note that files will NOT be compressed when the destination file ' 'already exists and has the same size as the original file.') + parser.add_argument('-r', '--relative-only', default=False, action='store_true', + help='Only pack assets that are referred to with a relative path (e.g. ' + 'starting with `//`.') def cli_pack(args): @@ -82,6 +85,9 @@ def create_packer(args, bpath: pathlib.Path, ppath: pathlib.Path, if args.compress: raise ValueError('S3 uploader does not support on-the-fly compression') + if args.relative_only: + raise ValueError('S3 uploader does not support the --relative-only option') + packer = create_s3packer(bpath, ppath, tpath) elif tpath.suffix.lower() == '.zip': from blender_asset_tracer.pack import zipped @@ -89,9 +95,11 @@ def create_packer(args, bpath: pathlib.Path, ppath: pathlib.Path, if args.compress: raise ValueError('ZIP packer does not support on-the-fly compression') - packer = zipped.ZipPacker(bpath, ppath, tpath, noop=args.noop) + packer = zipped.ZipPacker(bpath, ppath, tpath, noop=args.noop, + relative_only=args.relative_only) else: - packer = pack.Packer(bpath, ppath, tpath, noop=args.noop, compress=args.compress) + packer = pack.Packer(bpath, ppath, tpath, noop=args.noop, compress=args.compress, + relative_only=args.relative_only) if args.exclude: # args.exclude is a list, due to nargs='*', so we have to split and flatten. diff --git a/blender_asset_tracer/pack/__init__.py b/blender_asset_tracer/pack/__init__.py index 3a62b73..40cd15e 100644 --- a/blender_asset_tracer/pack/__init__.py +++ b/blender_asset_tracer/pack/__init__.py @@ -99,12 +99,14 @@ class Packer: target: pathlib.Path, *, noop=False, - compress=False) -> None: + compress=False, + relative_only=False) -> None: self.blendfile = bfile self.project = project self.target = target self.noop = noop self.compress = compress + self.relative_only = relative_only self._aborted = threading.Event() self._abort_lock = threading.RLock() @@ -233,6 +235,10 @@ class Packer: log.info('Excluding file: %s', asset_path) continue + if self.relative_only and not usage.asset_path.startswith(b'//'): + log.info('Skipping absolute path: %s', usage.asset_path) + continue + if usage.is_sequence: self._visit_sequence(asset_path, usage) else: diff --git a/tests/blendfiles/absolute_path.blend b/tests/blendfiles/absolute_path.blend new file mode 100644 index 0000000..58e3eb4 Binary files /dev/null and b/tests/blendfiles/absolute_path.blend differ diff --git a/tests/test_pack.py b/tests/test_pack.py index 4fed394..0fcfcbc 100644 --- a/tests/test_pack.py +++ b/tests/test_pack.py @@ -63,6 +63,7 @@ class PackTest(AbstractPackTest): self.assertEqual(self.tpath / pf, act.new_path, 'for %s' % pf) self.assertEqual({}, self.rewrites(packer)) + self.assertEqual(len(packed_files), len(packer._actions)) def test_strategise_rewrite(self): ppath = self.blendfiles / 'subdir' @@ -123,6 +124,29 @@ class PackTest(AbstractPackTest): self.assertEqual(b'LILib.002', rw_dbllink[1].block_name) self.assertEqual(b'//../material_textures.blend', rw_dbllink[1].asset_path) + def test_strategise_relative_only(self): + infile = self.blendfiles / 'absolute_path.blend' + + packer = pack.Packer(infile, self.blendfiles, self.tpath, + relative_only=True) + packer.strategise() + + packed_files = ( + 'absolute_path.blend', + # Linked with a relative path: + 'textures/Bricks/brick_dotted_04-color.jpg', + # This file links to textures/Textures/Buildings/buildings_roof_04-color.png, + # but using an absolute path, so that file should be skipped. + ) + for pf in packed_files: + path = self.blendfiles / pf + act = packer._actions[path] + self.assertEqual(pack.PathAction.KEEP_PATH, act.path_action, 'for %s' % pf) + self.assertEqual(self.tpath / pf, act.new_path, 'for %s' % pf) + + self.assertEqual(len(packed_files), len(packer._actions)) + self.assertEqual({}, self.rewrites(packer)) + def test_execute_rewrite_no_touch_origs(self): infile, _ = self._pack_with_rewrite()