diff --git a/bam/blend/blendfile_pack.py b/bam/blend/blendfile_pack.py index 78f879d..16fa7ed 100755 --- a/bam/blend/blendfile_pack.py +++ b/bam/blend/blendfile_pack.py @@ -111,7 +111,16 @@ def pack( # but in some cases we wan't to use a path higher up. # base_dir_src, blendfile_src, blendfile_dst, + + # the path to the top directory of the project's repository. + # the packed archive will reproduce the exact same hierarchy below that base path + # if set to None, it defaults to the given blendfile_src's directory. + # especially useful when used together with the warn_remap_externals option. + repository_base_path=None, + + # type of archive to produce (either ZIP or plain usual directory). mode='ZIP', + # optionally pass in the temp dir base_dir_dst_temp=None, paths_remap_relbase=None, @@ -140,6 +149,8 @@ def pack( # do _everything_ except to write the paths. # useful if we want to calculate deps to remap but postpone applying them. readonly=False, + # Warn when we found a dependency external to given repository_base_path. + warn_remap_externals=False, # dict of binary_edits: # {file: [(ofs, bytes), ...], ...} # ... where the file is the relative 'packed' location. @@ -201,7 +212,8 @@ def pack( import time t = time.time() - base_dir_src = os.path.dirname(blendfile_src) + base_dir_src = os.path.dirname(blendfile_src) if repository_base_path is None \ + else os.path.normpath(os.path.abspath(repository_base_path)) base_dir_dst = os.path.dirname(blendfile_dst) # _dbg(blendfile_src) # _dbg(blendfile_dst) @@ -351,6 +363,9 @@ def pack( path_src = blendfile_path_walker.utils.abspath(path_rel, fp.basedir) path_src = os.path.normpath(path_src) + if warn_remap_externals and b".." in os.path.relpath(path_src, base_dir_src): + yield report(" %s: %r\n" % (colorize("non-local", color='bright_yellow'), path_src)) + if filename_filter and not filename_filter(path_src): yield report(" %s: %r\n" % (colorize("exclude", color='yellow'), path_src)) continue diff --git a/bam/cli.py b/bam/cli.py index bb163b0..24ac84a 100755 --- a/bam/cli.py +++ b/bam/cli.py @@ -1329,8 +1329,10 @@ class bam_commands: paths, output, mode, + repository_base_path=None, all_deps=False, use_quiet=False, + warn_remap_externals=False, compress_level=-1, filename_filter=None, ): @@ -1380,8 +1382,10 @@ class bam_commands: output.encode('utf-8'), mode=mode, all_deps=all_deps, + repository_base_path=repository_base_path.encode('utf-8'), compress_level=compress_level, report=report, + warn_remap_externals=warn_remap_externals, use_variations=True, filename_filter=filename_filter, ): @@ -1763,6 +1767,15 @@ def create_argparse_pack(subparsers): # pack a blend with maximum compression for online downloads bam pack /path/to/scene.blend --output my_scene.zip --compress=best + + You may also pack a .blend while keeping your whole repository hierarchy by passing + the path to the top directory of the repository, and ask to be warned about dependencies paths + outside of that base path: + + .. code-block:: sh + + bam pack --repo="/path/to/repo" --warn-external /path/to/repo/path/to/scene.blend + """, formatter_class=argparse.RawDescriptionHelpFormatter, ) @@ -1780,6 +1793,15 @@ def create_argparse_pack(subparsers): choices=('ZIP', 'FILE'), help="Output file or a directory when multiple inputs are passed", ) + subparse.add_argument( + "--repo", dest="repository_base_path", metavar='DIR', required=False, + help="Base directory from which you want to keep existing hierarchy (usually to repository directory)," + "will default to packed blend file's directory if not specified", + ) + subparse.add_argument( + "--warn-external", dest="warn_remap_externals", action='store_true', + help="Warn for every dependency outside of given repository base path", + ) init_argparse_common(subparse, use_all_deps=True, use_quiet=True, use_compress_level=True, use_exclude=True) @@ -1791,8 +1813,10 @@ def create_argparse_pack(subparsers): ((os.path.splitext(args.paths[0])[0] + ".zip") if args.mode == 'ZIP' else None), args.mode, + repository_base_path=args.repository_base_path or None, all_deps=args.all_deps, use_quiet=args.use_quiet, + warn_remap_externals=args.warn_remap_externals, compress_level=args.compress_level, filename_filter=args.exclude, ),