X-Git-Url: https://git.madduck.net/etc/vim.git/blobdiff_plain/dd6c674e3a33ac6d20faea751764aeafecdf34c2..889a8d5dd27a73aa780e989a850bbdaaa9946a13:/src/black_primer/cli.py?ds=inline

diff --git a/src/black_primer/cli.py b/src/black_primer/cli.py
index 8360fc3..8524b59 100644
--- a/src/black_primer/cli.py
+++ b/src/black_primer/cli.py
@@ -1,13 +1,14 @@
 # coding=utf8
 
 import asyncio
+import json
 import logging
 import sys
 from datetime import datetime
 from pathlib import Path
 from shutil import rmtree, which
 from tempfile import gettempdir
-from typing import Any, Union, Optional
+from typing import Any, List, Optional, Union
 
 import click
 
@@ -42,12 +43,42 @@ def _handle_debug(
     return debug
 
 
+def load_projects(config_path: Path) -> List[str]:
+    with open(config_path) as config:
+        return sorted(json.load(config)["projects"].keys())
+
+
+# Unfortunately does import time file IO - but appears to be the only
+# way to get `black-primer --help` to show projects list
+DEFAULT_PROJECTS = load_projects(DEFAULT_CONFIG)
+
+
+def _projects_callback(
+    ctx: click.core.Context,
+    param: Optional[Union[click.core.Option, click.core.Parameter]],
+    projects: str,
+) -> List[str]:
+    requested_projects = set(projects.split(","))
+    available_projects = set(
+        DEFAULT_PROJECTS
+        if str(DEFAULT_CONFIG) == ctx.params["config"]
+        else load_projects(ctx.params["config"])
+    )
+
+    unavailable = requested_projects - available_projects
+    if unavailable:
+        LOG.error(f"Projects not found: {unavailable}. Available: {available_projects}")
+
+    return sorted(requested_projects & available_projects)
+
+
 async def async_main(
     config: str,
     debug: bool,
     keep: bool,
     long_checkouts: bool,
     no_diff: bool,
+    projects: List[str],
     rebase: bool,
     workdir: str,
     workers: int,
@@ -66,19 +97,19 @@ async def async_main(
             config,
             work_path,
             workers,
+            projects,
             keep,
             long_checkouts,
             rebase,
             no_diff,
         )
         return int(ret_val)
+
     finally:
         if not keep and work_path.exists():
             LOG.debug(f"Removing {work_path}")
             rmtree(work_path, onerror=lib.handle_PermissionError)
 
-    return -2
-
 
 @click.command(context_settings={"help_option_names": ["-h", "--help"]})
 @click.option(
@@ -88,6 +119,8 @@ async def async_main(
     type=click.Path(exists=True),
     show_default=True,
     help="JSON config file path",
+    # Eager - because config path is used by other callback options
+    is_eager=True,
 )
 @click.option(
     "--debug",
@@ -116,6 +149,13 @@ async def async_main(
     show_default=True,
     help="Disable showing source file changes in black output",
 )
+@click.option(
+    "--projects",
+    default=",".join(DEFAULT_PROJECTS),
+    callback=_projects_callback,
+    show_default=True,
+    help="Comma separated list of projects to run",
+)
 @click.option(
     "-R",
     "--rebase",