sdk_subtools: Implement CIPD export.

When run from the user script, default to exporting nothing, but list
subtools that are available for export. Provide a commandline argument
to select one or more. Users will need CIPD WRITER permissions for the
CIPD prefix configured for the selected subtool(s).

When run via the Build API, default to exporting all available subtools.

BUG=b:277992359
TEST=./run_tests + bin/build_sdk_subtools --export shellcheck

Change-Id: Ia26f04d51615b105288b34fd0176b10bc75f025a
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/4840805
Tested-by: Trent Apted <tapted@chromium.org>
Commit-Queue: Trent Apted <tapted@chromium.org>
Reviewed-by: Mike Frysinger <vapier@chromium.org>
diff --git a/scripts/build_sdk_subtools.py b/scripts/build_sdk_subtools.py
index 044ca7e..265a768 100644
--- a/scripts/build_sdk_subtools.py
+++ b/scripts/build_sdk_subtools.py
@@ -21,12 +21,12 @@
 """
 
 import argparse
-import logging
 import os
 from pathlib import Path
 import sys
 from typing import List, Optional, Protocol
 
+import chromite
 from chromite.lib import build_target_lib
 from chromite.lib import commandline
 from chromite.lib import constants
@@ -38,6 +38,8 @@
 
 assert sys.version_info >= (3, 8), "build_sdk_subtools uses Python 3.8 features"
 
+logger = chromite.ChromiteLogger.getLogger(__name__)
+
 
 # Affects where building occurs (e.g. /build/amd64-subtools-host) if not
 # overridden by --output-dir. Note this will be a chroot.
@@ -60,9 +62,6 @@
 max_files: 2
 paths: [{
     input: "/usr/bin/shellcheck"
-},{
-    input: "/usr/share/doc/*/LICENSE.gz"
-    ebuild_filter: "dev-util/shellcheck"
 }]
 """
 
@@ -73,9 +72,11 @@
     clean: bool
     setup_chroot: bool
     update_packages: bool
+    production: bool
     relaunch_for_setup: bool
     output_dir: Path
     packages: List[str]
+    export: List[str]
     jobs: int
 
     def Freeze(self) -> None:
@@ -107,6 +108,13 @@
         "Only export packages already installed in the subtools SDK.",
     )
 
+    parser.add_bool_argument(
+        "--production",
+        False,
+        "Use production environments for subtool exports.",
+        "Use staging environments for subtool exports.",
+    )
+
     parser.add_argument(
         "--output-dir",
         type=osutils.ExpandPath,
@@ -115,6 +123,14 @@
     )
 
     parser.add_argument(
+        "--export",
+        nargs="+",
+        default=[],
+        metavar="BUNDLE",
+        help="Packages to export (e.g. to CIPD). May require auth.",
+    )
+
+    parser.add_argument(
         "packages",
         nargs="*",
         default=["virtual/target-sdk-subtools"],
@@ -181,7 +197,14 @@
         except sysroot_lib.PackageInstallError as e:
             cros_build_lib.Die(e)
 
-    sdk_subtools.bundle_and_export()
+    installed = sdk_subtools.bundle_and_export(opts.production, opts.export)
+    if not installed.subtools:
+        logger.warn("No subtools available.")
+    elif not opts.export:
+        logger.notice(
+            "Use --export to export a package. Available:%s",
+            "".join(f"\n\t{x.summary}" for x in installed.subtools),
+        )
 
 
 def main(argv: Optional[List[str]] = None) -> Optional[int]:
@@ -219,7 +242,7 @@
 
     subtools_chroot = constants.DEFAULT_OUT_PATH / build_target.root.lstrip("/")
     chroot_args = ["--chroot", subtools_chroot]
-    logging.info("Initializing subtools builder in %s", subtools_chroot)
+    logger.info("Initializing subtools builder in %s", subtools_chroot)
 
     if opts.setup_chroot:
         # Get an SDK. TODO(b/277992359):