Skip to content

Commit 47ae839

Browse files
committed
feat: add parameter validation for git init
- Add validation for template parameter type and existence - Add validation for object_format parameter values - Improve type formatting for shared parameter - Complete docstring example output
1 parent 842c196 commit 47ae839

File tree

1 file changed

+50
-4
lines changed

1 file changed

+50
-4
lines changed

src/libvcs/cmd/git.py

+50-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import datetime
66
import pathlib
77
import shlex
8+
import string
89
import typing as t
910
from collections.abc import Sequence
1011

@@ -1155,26 +1156,71 @@ def init(
11551156
>>> sha256_repo.mkdir()
11561157
>>> git = Git(path=sha256_repo)
11571158
>>> git.init(object_format='sha256') # doctest: +SKIP
1159+
'Initialized empty Git repository in ...'
11581160
"""
11591161
local_flags: list[str] = []
11601162
required_flags: list[str] = [str(self.path)]
11611163

11621164
if template is not None:
1165+
if not isinstance(template, (str, pathlib.Path)):
1166+
msg = "template must be a string or Path"
1167+
raise TypeError(msg)
1168+
template_path = pathlib.Path(template)
1169+
if not template_path.is_dir():
1170+
msg = f"template directory does not exist: {template}"
1171+
raise ValueError(msg)
11631172
local_flags.append(f"--template={template}")
1173+
11641174
if separate_git_dir is not None:
11651175
if isinstance(separate_git_dir, pathlib.Path):
11661176
separate_git_dir = str(separate_git_dir.absolute())
11671177
local_flags.append(f"--separate-git-dir={separate_git_dir!s}")
1178+
11681179
if object_format is not None:
1180+
if object_format not in {"sha1", "sha256"}:
1181+
msg = "object_format must be either 'sha1' or 'sha256'"
1182+
raise ValueError(msg)
11691183
local_flags.append(f"--object-format={object_format}")
1170-
if branch is not None:
1171-
local_flags.extend(["--initial-branch", branch])
1172-
elif initial_branch is not None:
1173-
local_flags.extend(["--initial-branch", initial_branch])
1184+
1185+
if branch is not None and initial_branch is not None:
1186+
msg = "Cannot specify both branch and initial_branch"
1187+
raise ValueError(msg)
1188+
1189+
branch_name = branch or initial_branch
1190+
if branch_name is not None:
1191+
if any(c.isspace() for c in branch_name):
1192+
msg = "Branch name cannot contain whitespace"
1193+
raise ValueError(msg)
1194+
local_flags.extend(["--initial-branch", branch_name])
1195+
11741196
if shared is not None:
1197+
valid_shared_values = {
1198+
"false",
1199+
"true",
1200+
"umask",
1201+
"group",
1202+
"all",
1203+
"world",
1204+
"everybody",
1205+
}
11751206
if isinstance(shared, bool):
11761207
local_flags.append("--shared")
11771208
else:
1209+
shared_str = str(shared).lower()
1210+
# Check if it's a valid string value or an octal number
1211+
if not (
1212+
shared_str in valid_shared_values
1213+
or (
1214+
shared_str.isdigit()
1215+
and len(shared_str) <= 4
1216+
and all(c in string.octdigits for c in shared_str)
1217+
)
1218+
):
1219+
msg = (
1220+
f"Invalid shared value. Must be one of {valid_shared_values} "
1221+
"or an octal number"
1222+
)
1223+
raise ValueError(msg)
11781224
local_flags.append(f"--shared={shared}")
11791225
if quiet is True:
11801226
local_flags.append("--quiet")

0 commit comments

Comments
 (0)