def compress_package()

in src/sfctl/custom_app.py [0:0]


def compress_package(app_dir, output_dir):
    """
    Compress to the location passed in (output_dir). Note that it is not the entire package
    which is compressed, but rather, only some inside parts of the app package folder.

    Check if the folder has the correct structure for a service fabric application. If
    not, raise an exception alerting user of bad folder structure.

    ZIP64 functionality is present for Python
    versions 3.4 and above.

    For example, if app_dir = C:/SomeFolder/WordCountApp
    and if output_dir = C:/SomeLocation,
    then the following will be created: C:/SomeLocation/WordCountApp

    :param app_dir: (str) An absolute path to an application package to be compressed

    :param output_dir: (str) An absolute path to the location to output the zipped dir

    :return: Nothing, or a CLIError exception
    """

    # Check if we're dealing with a dir in _check_folder_structure_and_get_dirs instead of
    # in this function

    # Normalize slashes, etc, in app_dir and output_dir
    app_dir = _normalize_path(app_dir)
    output_dir = _normalize_path(output_dir)

    compress_copy = IgnoreCopy()

    # Exception will be raised if the package isn't the correct structure
    # This list may be empty in the case of an already compressed application package
    compress_copy.dirs_to_ignore = _check_folder_structure_and_get_dirs(app_dir)

    if not compress_copy.dirs_to_ignore:
        print("Nothing to copy")

    app_name = os.path.basename(app_dir)
    copy_output_path = os.path.join(output_dir, app_name)

    # Get the relative paths under app_name of dirs_to_copy so that we know
    # where to place the new zipped file
    relative_paths_to_compress = []
    for directory in compress_copy.dirs_to_ignore:

        rel_path = directory[len(app_dir):]
        relative_paths_to_compress.append(rel_path.lstrip('\\').lstrip('/'))

    try:
        # Copy everything except the one we want to zip. Those we will do manually
        shutil.copytree(app_dir, copy_output_path, ignore=compress_copy.ignore_copy)

        i = 0
        for directory in relative_paths_to_compress:

            dir_to_compress = compress_copy.dirs_to_ignore[i]

            # Example: shutil.make_archive('C:\\Users\\user\\Downloads\\Code', 'zip',
            # root_dir='C:\\WordCountV1Original\\WordCountServicePkg\\Code')
            # The above will copy the contents of root_dir into the path given as the first
            # parameter, with a .zip extension, so that a Code.zip will be created in Downloads

            # Note for python versions before 3.4, zipping of folders larger than 2GB isn't
            # supported
            # It is more work and code to support Python 2.7 for this, and since we do plan to
            # deprecate support for Python 2.7 in the future, we will just not add it here.
            shutil.make_archive(os.path.join(copy_output_path, directory), 'zip', dir_to_compress)

            i += 1

    except zipfile.LargeZipFile as ex:
        raise CLIError('Compression failed due to file too large. If you have Python 2.7, '
                       'upgrading to 3.5 or higher will fix the issue. Please clean up '
                       'location ' + output_dir + '\n' + str(ex))

    except Exception as ex:
        raise CLIError(str.format('Compression failed due to {0}. Please clean up '
                                  'location {1}', str(ex), output_dir))