Skip to content

Commit 0934ea8

Browse files
committed
fix: improve init naming
1 parent 3d00409 commit 0934ea8

4 files changed

Lines changed: 28 additions & 10 deletions

File tree

docs/source/cli-init.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,16 @@ kernels init my-user/my-kernel --overwrite
4747
`kernels init` prints suggested next steps after creating the project. A typical flow looks like:
4848

4949
```bash
50-
cd my_kernel
50+
cd my-kernel
5151
cachix use huggingface
5252
nix run -L --max-jobs 1 --cores 8 .#build-and-copy
5353
uv run example.py
5454
```
5555

5656
## Notes
5757

58-
- The `<repo>` part is normalized to lowercase, and `-` is replaced with `_`. For example, `my-user/My-Kernel` becomes a directory named `my_kernel` and a repo id `my-user/my_kernel`.
58+
- The `<repo>` part is normalized to lowercase with dashes preferred. For example, `my-user/My_Kernel` becomes a directory named `my-kernel` and a repo id `my-user/my-kernel`.
59+
- Python package names use underscores (e.g., `my_kernel`) since dashes are not valid in Python identifiers.
5960
- `--backends` can be one of: `cpu`, `cuda`, `metal`, `rocm`, `xpu`, `npu`, or `all`.
6061
- If the target directory already exists and is not empty, `kernels init` exits with an error unless `--overwrite` is set.
6162
- The project is initialized as a Git repo (via `git init`) because Nix flakes require it.

kernels/src/kernels/cli/init.py

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,26 @@ def parse_kernel_name(value: str) -> NamedTuple:
2323
if "/" in name or "\\" in name: # validate kernel name
2424
raise argparse.ArgumentTypeError("repo name cannot contain path separators")
2525

26-
name = name.lower().replace("-", "_") # normalize name
27-
RepoInfo = NamedTuple("RepoInfo", [("name", str), ("owner", str), ("repo_id", str)])
28-
return RepoInfo(name=name, owner=owner, repo_id=f"{owner}/{name}")
26+
# Display name uses dashes (for repo name, directory, build.toml name)
27+
display_name = name.lower().replace("_", "-")
28+
# Normalized name uses underscores (for Python package names)
29+
normalized_name = name.lower().replace("-", "_")
30+
31+
RepoInfo = NamedTuple(
32+
"RepoInfo",
33+
[("name", str), ("normalized_name", str), ("owner", str), ("repo_id", str)],
34+
)
35+
return RepoInfo(
36+
name=display_name,
37+
normalized_name=normalized_name,
38+
owner=owner,
39+
repo_id=f"{owner}/{display_name}",
40+
)
2941

3042

3143
def run_init(args: Namespace) -> None:
3244
kernel_name = args.kernel_name.name
45+
normalized_name = args.kernel_name.normalized_name
3346
repo_id = args.kernel_name.repo_id
3447
backends = KNOWN_BACKENDS if "all" in args.backends else set(args.backends)
3548

@@ -54,7 +67,9 @@ def run_init(args: Namespace) -> None:
5467
template_dir = Path(
5568
snapshot_download(repo_id=args.template_repo, repo_type="model")
5669
)
57-
_init_from_local_template(template_dir, target_dir, kernel_name, repo_id)
70+
_init_from_local_template(
71+
template_dir, target_dir, kernel_name, normalized_name, repo_id
72+
)
5873

5974
if backends:
6075
_update_build_backends(target_dir / "build.toml", backends)
@@ -84,12 +99,13 @@ def _init_from_local_template(
8499
template_dir: Path,
85100
target_dir: Path,
86101
kernel_name: str,
102+
normalized_name: str,
87103
repo_id: str,
88104
) -> None:
89105
# Placeholder mappings
90106
replacements = {
91107
"__KERNEL_NAME__": kernel_name,
92-
"__KERNEL_NAME_NORMALIZED__": kernel_name,
108+
"__KERNEL_NAME_NORMALIZED__": normalized_name,
93109
"__REPO_ID__": repo_id,
94110
}
95111

kernels/tests/test_init.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ def e2e_init(backends: list[str]) -> None:
1616
backends=backends,
1717
overwrite=False,
1818
)
19+
expected_dir_name = "test-kernel"
1920
expected_normalized_name = "test_kernel"
2021
expected_backend_dirs = {
2122
Path(f"{expected_normalized_name}_{backend}") for backend in args.backends
@@ -43,8 +44,8 @@ def e2e_init(backends: list[str]) -> None:
4344
try:
4445
run_init(args)
4546

46-
# make sure normalized dir was created
47-
target_dir = Path(tmpdir) / expected_normalized_name
47+
# make sure dir was created
48+
target_dir = Path(tmpdir) / expected_dir_name
4849
if not target_dir.exists():
4950
raise AssertionError(f"Target directory was not created: {target_dir}")
5051

kernels/uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)