diff --git a/docs/source/builder/writing-kernels.md b/docs/source/builder/writing-kernels.md index c5a32d5..0144f7a 100644 --- a/docs/source/builder/writing-kernels.md +++ b/docs/source/builder/writing-kernels.md @@ -320,3 +320,14 @@ $ nix run .#ciTests.torch210-cxx11-cpu-x86_64-linux When running the tests on a non-NixOS systems, make sure that [the CUDA driver library can be found](https://danieldk.eu/Software/Nix/Nix-CUDA-on-non-NixOS-systems#solutions). + +## Kernel docs + +We provide a utility to generate a system card for a given kernel, utilizing +information from the `build.toml` and metadata. This system card provides a +reasonable starting point and is meant to be edited afterward by the kernel +developer. + +To generate the card, use the `kernels create-and-upload-card ...` command. +Alternatively, specify `--create_card` while uploading the kernel builds +through `kernels upload`. Refer to the [documentation](../cli.md) to know more. \ No newline at end of file diff --git a/kernels/src/kernels/cli/__init__.py b/kernels/src/kernels/cli/__init__.py index 8d84df4..8143d12 100644 --- a/kernels/src/kernels/cli/__init__.py +++ b/kernels/src/kernels/cli/__init__.py @@ -92,6 +92,28 @@ def main(): default=None, help="If set, the upload will be made to a particular branch of the provided `repo-id`.", ) + upload_parser.add_argument( + "--create-card", + action="store_true", + help="If set, a templated system card will be generated from the kernel.", + ) + upload_parser.add_argument( + "--card-path", + type=str, + default=None, + help="Path to save the generated card to (only used with --create-card).", + ) + upload_parser.add_argument( + "--description", + type=str, + default=None, + help="Description to introduce the kernel (only used with --create-card).", + ) + upload_parser.add_argument( + "--create-pr", + action="store_true", + help="If set, it will create a PR on the repo-id (only used with --create-card).", + ) upload_parser.add_argument( "--private", action="store_true", @@ -344,6 +366,10 @@ def upload_kernels(args): branch=args.branch, private=args.private, ) + if args.create_card: + if args.card_path is None: + args.card_path = str(Path(args.kernel_dir).resolve() / "README.md") + create_and_upload_card(args) def create_and_upload_card(args): diff --git a/kernels/tests/test_kernel_upload.py b/kernels/tests/test_kernel_upload.py index 11928bf..aed398a 100644 --- a/kernels/tests/test_kernel_upload.py +++ b/kernels/tests/test_kernel_upload.py @@ -4,6 +4,7 @@ import tempfile from dataclasses import dataclass from pathlib import Path +from unittest.mock import patch import pytest @@ -30,6 +31,10 @@ class UploadArgs: repo_id: None private: False branch: None + create_card: bool = False + card_path: str = None + description: str = None + create_pr: bool = False def next_filename(path: Path) -> Path: @@ -120,3 +125,20 @@ def test_kernel_upload_deletes_as_expected(): str(filename_to_change) in k for k in repo_filenames ), f"{repo_filenames=}" _get_hf_api().delete_repo(repo_id=REPO_ID) + + +@patch("kernels.cli.create_and_upload_card") +@patch("kernels.cli.upload_kernels_dir") +def test_kernel_upload_calls_create_and_upload_card(mock_upload_dir, mock_create_card): + with tempfile.TemporaryDirectory() as tmpdir: + args = UploadArgs( + kernel_dir=tmpdir, + repo_id=REPO_ID, + private=False, + branch=None, + create_card=True, + ) + upload_kernels(args) + + mock_create_card.assert_called_once_with(args) + assert args.card_path == str(Path(tmpdir).resolve() / "README.md")