Repository: carbon-language/carbon-lang
File: scripts/create_compdb.py (Python)

Code before:
        # tree_sitter is excluded here because it causes the query to failure on
        # `@platforms`.
        "      deps(//... except //utils/tree_sitter/...))"
        ")"
    )
    log_to = None
    if not logtostderr:
        log_to = subprocess.DEVNULL
    generated_file_labels = subprocess.check_output(
        [bazel, "query", "--keep_going", "--output=label", kinds_query],
        stderr=log_to,
        encoding="utf-8",
    ).splitlines()
    if dump_files:
        for f in sorted(generated_file_labels):
            print(f)
        sys.exit(0)
    print(f"Found {len(generated_file_labels)} generated files...", flush=True)

    # Directly build these labels so that indexing can find them. Allow this to
    # fail in case there are build errors in the client, and just warn the user
    # that they may be missing generated files.
    subprocess.check_call(
        [bazel, "build", "--keep_going", "--remote_download_outputs=toplevel"]
        + generated_file_labels
        # We also need the Bazel C++ runfiles that aren't "generated", but not
        # linked into place until built.
        + ["@bazel_tools//tools/cpp/runfiles:runfiles"]
    )


def _get_config_for_entry(entry: Dict[str, Any]) -> str:
    """Returns the configuration for a compile command entry."""
    arguments = entry.get("arguments")

    # Only handle files where the object file argument is easily found as
    # the last argument, which matches the expected structure from Bazel.
    if not arguments or len(arguments) < 2 or arguments[-2] != "-o":
        return "unknown"
    obj_file = arguments[-1]

    # The configuration is the name of the subdirectory of `bazel-out`.
    if not obj_file.startswith("bazel-out/"):
        return "unknown"
    return str(obj_file.split("/")[1])


def _filter_compilation_database(file_path: str) -> None:
    """Filters out duplicate exec-configuration entries from the compilation
    database.
    """

Review comment (suggestion):
```suggestion
        # We also need the Bazel C++ runfiles that aren't "generated", but are not
```

Code after:
        "      deps(//... except //utils/tree_sitter/...))"
        ")"
    )
    log_to = None
    if not logtostderr:
        log_to = subprocess.DEVNULL
    generated_file_labels = subprocess.check_output(
        [bazel, "query", "--keep_going", "--output=label", kinds_query],
        stderr=log_to,
        encoding="utf-8",
    ).splitlines()
    if dump_files:
        for f in sorted(generated_file_labels):
            print(f)
        sys.exit(0)
    print(f"Found {len(generated_file_labels)} generated files...", flush=True)

    # Directly build these labels so that indexing can find them. Allow this to
    # fail in case there are build errors in the client, and just warn the user
    # that they may be missing generated files.
    subprocess.check_call(
        [bazel, "build", "--keep_going", "--remote_download_outputs=toplevel"]
        + generated_file_labels
        # We also need the Bazel C++ runfiles that aren't "generated", but are
        # not linked into place until built.
        + ["@bazel_tools//tools/cpp/runfiles:runfiles"]
    )


def main() -> None:
    parser = argparse.ArgumentParser(
        description=__doc__,
        allow_abbrev=False,
    )
    parser.add_argument(
        "--alsologtostderr",
        action="store_true",
        help="Prints subcommand errors to stderr (default: False)",
    )
    parser.add_argument(
        "--dump-files",
        action="store_true",
        help="Dumps the full list of generated files (default: False)",
    )

    args = parser.parse_args()
    scripts_utils.chdir_repo_root()
    bazel = scripts_utils.locate_bazel()

    _build_generated_files(bazel, args.alsologtostderr, args.dump_files)