# Buggy code
def _build_files_manifest(b_collection_path, namespace, name):
    # Contains tuple of (b_filename, only root) where 'only root' means to only ignore the file in the root dir
    b_ignore_files = frozenset(
        [
            (b"*.pyc", False),
            (b"*.retry", False),
            (b".git", True),
            (to_bytes("{0}-{1}-*.tar.gz".format(namespace, name)), True),
        ]
    )
    b_ignore_dirs = frozenset(
        [
            (b"CVS", False),
            (b".bzr", False),
            (b".hg", False),
            (b".git", False),
            (b".svn", False),
            (b"__pycache__", False),
            (b".tox", False),
        ]
    )

    entry_template = {
        "name": None,
        "ftype": None,
        "chksum_type": None,
        "chksum_sha256": None,
        "format": MANIFEST_FORMAT,
    }
    manifest = {
        "files": [
            {
                "name": ".",
                "ftype": "dir",
                "chksum_type": None,
                "chksum_sha256": None,
                "format": MANIFEST_FORMAT,
            },
        ],
        "format": MANIFEST_FORMAT,
    }

    def _walk(b_path, b_top_level_dir):
        is_root = b_path == b_top_level_dir

        for b_item in os.listdir(b_path):
            b_abs_path = os.path.join(b_path, b_item)
            b_rel_base_dir = (
                b"" if b_path == b_top_level_dir else b_path[len(b_top_level_dir) + 1 :]
            )
            rel_path = to_text(
                os.path.join(b_rel_base_dir, b_item), errors="surrogate_or_strict"
            )

            if os.path.isdir(b_abs_path):
                if any(
                    b_item == b_path
                    for b_path, root_only in b_ignore_dirs
                    if not root_only or root_only == is_root
                ):
                    display.vvv(
                        "Skipping '%s' for collection build" % to_text(b_abs_path)
                    )
                    continue

                if os.path.islink(b_abs_path):
                    b_link_target = os.path.realpath(b_abs_path)

                    if not b_link_target.startswith(b_top_level_dir):
                        display.warning(
                            "Skipping '%s' as it is a symbolic link to a directory outside the collection"
                            % to_text(b_abs_path)
                        )
                        continue

                manifest_entry = entry_template.copy()
                manifest_entry["name"] = rel_path
                manifest_entry["ftype"] = "dir"

                manifest["files"].append(manifest_entry)

                _walk(b_abs_path, b_top_level_dir)
            else:
                if b_item == b"galaxy.yml":
                    continue
                elif any(
                    fnmatch.fnmatch(b_item, b_pattern)
                    for b_pattern, root_only in b_ignore_files
                    if not root_only or root_only == is_root
                ):
                    display.vvv(
                        "Skipping '%s' for collection build" % to_text(b_abs_path)
                    )
                    continue

                manifest_entry = entry_template.copy()
                manifest_entry["name"] = rel_path
                manifest_entry["ftype"] = "file"
                manifest_entry["chksum_type"] = "sha256"
                manifest_entry["chksum_sha256"] = secure_hash(
                    b_abs_path, hash_func=sha256
                )

                manifest["files"].append(manifest_entry)

    _walk(b_collection_path, b_collection_path)

    return manifest


# Traceback (KeyError)
Exception, this is probably a bug: "filename 'tests/unit/modules/placebo_recordings/aws_direct_connect_link_aggregation_group/nonexistent_lag_status' not found"
the full traceback was:
Traceback (most recent call last):
File "/home/bcoca/work/ansible/bin/ansible-galaxy", line 123, in <module>
exit_code = cli.run()
File "/home/bcoca/work/ansible/lib/ansible/cli/galaxy.py", line 490, in run
context.CLIARGS['func']()
File "/home/bcoca/work/ansible/lib/ansible/cli/galaxy.py", line 1057, in execute_install
self._execute_install_collection(collection_requirements, collection_path)
File "/home/bcoca/work/ansible/lib/ansible/cli/galaxy.py", line 1079, in _execute_install_collection
no_deps, force, force_with_deps, allow_pre_release=allow_pre_release)
File "/home/bcoca/work/ansible/lib/ansible/galaxy/collection.py", line 675, in install_collections
collection.install(output_path, b_temp_path)
File "/home/bcoca/work/ansible/lib/ansible/galaxy/collection.py", line 250, in install
self.install_artifact(b_collection_path, b_temp_path)
File "/home/bcoca/work/ansible/lib/ansible/galaxy/collection.py", line 275, in install_artifact
_extract_tar_dir(collection_tar, file_name, b_collection_path)
File "/home/bcoca/work/ansible/lib/ansible/galaxy/collection.py", line 1387, in _extract_tar_dir
tar_member = tar.getmember(to_native(dirname, errors='surrogate_or_strict'))
File "/usr/lib/python3.7/tarfile.py", line 1752, in getmember
raise KeyError("filename %r not found" % name)
KeyError: "filename 'tests/unit/modules/placebo_recordings/aws_direct_connect_link_aggregation_group/nonexistent_lag_status' not found"

# Fixed code
def _build_files_manifest(b_collection_path, namespace, name):
    # Contains tuple of (b_filename, only root) where 'only root' means to only ignore the file in the root dir
    b_ignore_files = frozenset(
        [
            (b"*.pyc", False),
            (b"*.retry", False),
            (b".git", True),
            (to_bytes("{0}-{1}-*.tar.gz".format(namespace, name)), True),
        ]
    )
    b_ignore_dirs = frozenset(
        [
            (b"CVS", False),
            (b".bzr", False),
            (b".hg", False),
            (b".git", False),
            (b".svn", False),
            (b"__pycache__", False),
            (b".tox", False),
        ]
    )

    entry_template = {
        "name": None,
        "ftype": None,
        "chksum_type": None,
        "chksum_sha256": None,
        "format": MANIFEST_FORMAT,
    }
    manifest = {
        "files": [
            {
                "name": ".",
                "ftype": "dir",
                "chksum_type": None,
                "chksum_sha256": None,
                "format": MANIFEST_FORMAT,
            },
        ],
        "format": MANIFEST_FORMAT,
    }

    def _walk(b_path, b_top_level_dir):
        is_root = b_path == b_top_level_dir

        for b_item in os.listdir(b_path):
            b_abs_path = os.path.join(b_path, b_item)
            b_rel_base_dir = (
                b"" if b_path == b_top_level_dir else b_path[len(b_top_level_dir) + 1 :]
            )
            rel_path = to_text(
                os.path.join(b_rel_base_dir, b_item), errors="surrogate_or_strict"
            )

            if os.path.isdir(b_abs_path):
                if any(
                    b_item == b_path
                    for b_path, root_only in b_ignore_dirs
                    if not root_only or root_only == is_root
                ):
                    display.vvv(
                        "Skipping '%s' for collection build" % to_text(b_abs_path)
                    )
                    continue

                if os.path.islink(b_abs_path):
                    b_link_target = os.path.realpath(b_abs_path)

                    if not _is_child_path(b_link_target, b_top_level_dir):
                        display.warning(
                            "Skipping '%s' as it is a symbolic link to a directory outside the collection"
                            % to_text(b_abs_path)
                        )
                        continue

                manifest_entry = entry_template.copy()
                manifest_entry["name"] = rel_path
                manifest_entry["ftype"] = "dir"

                manifest["files"].append(manifest_entry)

                if not os.path.islink(b_abs_path):
                    _walk(b_abs_path, b_top_level_dir)
            else:
                if b_item == b"galaxy.yml":
                    continue
                elif any(
                    fnmatch.fnmatch(b_item, b_pattern)
                    for b_pattern, root_only in b_ignore_files
                    if not root_only or root_only == is_root
                ):
                    display.vvv(
                        "Skipping '%s' for collection build" % to_text(b_abs_path)
                    )
                    continue

                # Handling of file symlinks occur in _build_collection_tar, the manifest for a symlink is the same for
                # a normal file.
                manifest_entry = entry_template.copy()
                manifest_entry["name"] = rel_path
                manifest_entry["ftype"] = "file"
                manifest_entry["chksum_type"] = "sha256"
                manifest_entry["chksum_sha256"] = secure_hash(
                    b_abs_path, hash_func=sha256
                )

                manifest["files"].append(manifest_entry)

    _walk(b_collection_path, b_collection_path)

    return manifest