Repository: psf/black
File: src/black_primer/lib.py (Python)

Code before:
        func(path)  # Try the error causing delete operation again
    else:
        raise


async def load_projects_queue(
    config_path: Path,
    projects_to_run: Optional[Set[str]],
) -> Tuple[Dict[str, Any], asyncio.Queue]:
    """Load project config and fill queue with all the project names"""
    with config_path.open("r") as cfp:
        config = json.load(cfp)

    # TODO: Offer more options here
    # e.g. Run on X random packages etc.
    project_names = sorted(config["projects"].keys())
    queue: asyncio.Queue = asyncio.Queue(maxsize=len(project_names))
    for project in project_names:
        if projects_to_run is None or project in projects_to_run:
            await queue.put(project)
            if projects_to_run:
                projects_to_run.remove(project)

    if projects_to_run:
        LOG.error(f"Project not found: {projects_to_run}")
        LOG.error(f"Available projects: {project_names}")

    return config, queue


async def project_runner(
    idx: int,
    config: Dict[str, Any],
    queue: asyncio.Queue,
    work_path: Path,
    results: Results,
    long_checkouts: bool = False,
    rebase: bool = False,
    keep: bool = False,
    no_diff: bool = False,
) -> None:
    """Check out project and run Black on it + record result"""
    loop = asyncio.get_event_loop()
    py_version = f"{version_info[0]}.{version_info[1]}"
    while True:
        try:
            project_name = queue.get_nowait()
        except asyncio.QueueEmpty:
            LOG.debug(f"project_runner {idx} exiting")
            return
        LOG.debug(f"worker {idx} working on {project_name}")

Review comment (suggestion):
This should be done in the CLI callback, the checking of projects (whether they are available or not). There isn't a need to print the `Available projects` here IMO if you want to keep it knock it down to level `INFO` or merge it with the above log.

Code after:
    else:
        raise


async def load_projects_queue(
    config_path: Path,
    projects_to_run: List[str],
) -> Tuple[Dict[str, Any], asyncio.Queue]:
    """Load project config and fill queue with all the project names"""
    with config_path.open("r") as cfp:
        config = json.load(cfp)

    # TODO: Offer more options here
    # e.g. Run on X random packages etc.
    queue: asyncio.Queue = asyncio.Queue(maxsize=len(projects_to_run))
    for project in projects_to_run:
        await queue.put(project)

    return config, queue


async def project_runner(
    idx: int,
    config: Dict[str, Any],
    queue: asyncio.Queue,
    work_path: Path,
    results: Results,
    long_checkouts: bool = False,
    rebase: bool = False,
    keep: bool = False,
    no_diff: bool = False,
) -> None:
    """Check out project and run Black on it + record result"""
    loop = asyncio.get_event_loop()
    py_version = f"{version_info[0]}.{version_info[1]}"
    while True:
        try:
            project_name = queue.get_nowait()
        except asyncio.QueueEmpty:
            LOG.debug(f"project_runner {idx} exiting")
            return
        LOG.debug(f"worker {idx} working on {project_name}")

        project_config = config["projects"][project_name]

        # Check if disabled by config
        if "disabled" in project_config and project_config["disabled"]:
            results.stats["disabled"] += 1
            LOG.info(f"Skipping {project_name} as it's disabled via config")
            continue