<commit_before>#!/usr/bin/env python3

# Copyright 2022 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Setup clangd for the given board and image"""

import argparse
import glob
import multiprocessing
import os
import shutil
import subprocess
import sys
from pathlib import Path
from typing import List, Optional


def fetch_boards(ec_root: Path) -> Optional[List[str]]:
    """Return a list of boards."""

    base = str(ec_root) + "/board/"

    boards = glob.glob(base + "*")
    if boards is None:
        return None

    return [b[len(base) :] for b in boards]


# We would use image: Literal["RW", "RO"], but it was only added in Python 3.8.
def build(ec_root: Path, board: str, image: str) -> Optional[Path]:
    """Build the correct compile_commands.json."""

    target = Path(f"build/{board}/{image}/compile_commands.json")
    cmd = [
        "make",
        f"-j{multiprocessing.cpu_count()}",
        "BOARD=" + board,
        str(target),
    ]

    print(" ".join(cmd))
    status = subprocess.run(cmd, check=False, cwd=ec_root)

    if status.returncode != 0:
        return None
    return target


def copy(ec_root: Path, target: Path) -> None:
    """Copy the correct compile_commands.json to the EC root."""

    print(f"Copying {target} to EC root.")
    root_cmds_path = ec_root / "compile_commands.json"
    if root_cmds_path.exists():
        root_cmds_path.unlink()
    shutil.copy(ec_root / target, root_cmds_path)


def link(ec_root: Path, target: Path) -> None:
    """Link the correct compile_commands.json to the EC root."""

    print(f"Linking compile_comands.json to {target}")
    root_cmds_path = ec_root / "compile_commands.json"
    if root_cmds_path.exists():
        root_cmds_path.unlink()
    root_cmds_path.symlink_to(target)


def main(argv: List[str]) -> int:
    """Build compile_commands.json for the board/image and lnk to it."""

    parser = argparse.ArgumentParser(description=__doc__)
    # There are far too many boards to show in help message, so we omit the
    # choice option and manually check the boards below.
    parser.add_argument("board", help="EC board name")
    parser.add_argument(
        "image",
        help="EC firmware copy",
        nargs="?",
        choices=["ro", "rw"],
        default="rw",
        type=str.lower,
    )
    parser.add_argument(
        "-s", help="symbolically link instead of copying.", action="store_true"
    )
    args = parser.parse_args(argv)

    ec_root = Path(os.path.relpath(os.path.dirname(__file__) + "/.."))

    boards = fetch_boards(ec_root)
    if boards is None:
        parser.error("Can't find boards directory.")
    if not args.board in boards:
        parser.error(f"Board '{args.board}' does not exist.")

    target = build(ec_root, args.board, args.image.upper())
    if target is None:
        print("Failed to build compile_commands.json")
        return 1<commit_msg>util: Add --os support to clangd_config.py<commit_after>#!/usr/bin/env python3

# Copyright 2022 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Setup clangd for the given board and image"""

import argparse
import glob
import multiprocessing
import os
import shutil
import subprocess
import sys
from pathlib import Path
from typing import List, Optional


def ec_fetch_boards(ec_root: Path) -> Optional[List[str]]:
    """Return a list of EC boards seen."""

    base = str(ec_root) + "/board/"

    boards = glob.glob(base + "*")
    if boards is None:
        return None

    return [b[len(base) :] for b in boards]


def zephyr_fetch_projects(ec_root: Path) -> Optional[List[str]]:
    """Return a list of Zephyr projects seen."""

    base = str(ec_root) + "/zephyr/projects/"

    boards = glob.glob(base + "*")
    if boards is None:
        return None

    return [b[len(base) :] for b in boards]


# We would use image: Literal["RW", "RO"], but it was only added in Python 3.8.
def ec_build(ec_root: Path, board: str, image: str) -> Optional[Path]:
    """Build the correct compile_commands.json for EC board/image."""

    target = Path(f"build/{board}/{image}/compile_commands.json")
    cmd = [
        "make",
        f"-j{multiprocessing.cpu_count()}",
        "BOARD=" + board,
        str(target),
    ]

    print(" ".join(cmd))
    status = subprocess.run(cmd, check=False, cwd=ec_root)

    if status.returncode != 0:
        return None
    return target


# We would use image: Literal["RW", "RO"], but it was only added in Python 3.8.
def zephyr_build(ec_root: Path, board: str, image: str) -> Optional[Path]:
    """Build the correct compile_commands.json for Zephyr board/image"""

    raise NotImplementedError("Zephyr is currently unsupported.")


def copy(ec_root: Path, target: Path) -> None:
    """Copy the correct compile_commands.json to the EC root."""

    print(f"Copying {target} to EC root.")
    root_cmds_path = ec_root / "compile_commands.json"
    if root_cmds_path.exists():
        root_cmds_path.unlink()
    shutil.copy(ec_root / target, root_cmds_path)


def link(ec_root: Path, target: Path) -> None:
    """Link the correct compile_commands.json to the EC root."""

    print(f"Linking compile_comands.json to {target}")
    root_cmds_path = ec_root / "compile_commands.json"
    if root_cmds_path.exists():
        root_cmds_path.unlink()
    root_cmds_path.symlink_to(target)


def main(argv: List[str]) -> int:
    """Build compile_commands.json for the board/image and lnk to it."""

    parser = argparse.ArgumentParser(description=__doc__)
    # There are far too many boards to show in help message, so we omit the
    # choice option and manually check the boards below.
    parser.add_argument("board", help="EC board name")
    parser.add_argument(
        "image",
        help="EC firmware copy",
        nargs="?",
        choices=["ro", "rw"],
        default="rw",
        type=str.lower,
    )
    parser.add_argument(
        "-s", help="symbolically link instead of copying.", action="store_true"
    )
    parser.add_argument(
        "--os",
        help="OS used to build board",
        nargs="?",
        choices=["auto", "ec", "zephyr"],
        default="auto",
        type=str.lower,
    )
    args = parser.parse_args(argv)

    ec_root = Path(os.path.relpath(os.path.dirname(__file__) + "/.."))

    ec_boards = ec_fetch_boards(ec_root)
    if ec_boards is None:
        parser.error("Can't find EC boards directory.")

    zephyr_projects = zephyr_fetch_projects(ec_root)
    if zephyr_projects is None:
        parser.error("Can't find Zephyr projects directory.")

    is_in_ec = args.board in ec_boards
    is_in_zephyr = args.board in zephyr_projects

    if not is_in_ec and not is_in_zephyr:
        parser.error(f"Board '{args.board}' does not exist.")

    # When "os" is auto, try Zephyr first, fall back to EC.
    os_selection = args.os
    if os_selection == "auto":
        if is_in_zephyr:
            os_selection = "zephyr"
        else:
            os_selection = "ec"

    print(f"Configuring for {os_selection}.")

    if os_selection == "ec":
        target = ec_build(ec_root, args.board, args.image.upper())
    else:
        target = zephyr_build(ec_root, args.board, args.image.upper())

    if target is None:
        print("Failed to build compile_commands.json")
        return 1
{'fraction_non_alphanumeric': 0.12283295256013976, 'fraction_numerical': 0.0026878107781212203, 'mean_word_length': 3.0357917570498913, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6306022', 'n_tokens_mistral': 2410, 'n_tokens_neox': 2334, 'n_words': 701}