Skip to content

Commit af7d69d

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 2b1a64c commit af7d69d

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
@@ -6,6 +6,7 @@
66
import pathlib
77
import re
88
import shlex
9+
import string
910
import typing as t
1011
from collections.abc import Sequence
1112

@@ -1159,26 +1160,71 @@ def init(
11591160
>>> sha256_repo.mkdir()
11601161
>>> git = Git(path=sha256_repo)
11611162
>>> git.init(object_format='sha256') # doctest: +SKIP
1163+
'Initialized empty Git repository in ...'
11621164
"""
11631165
local_flags: list[str] = []
11641166
required_flags: list[str] = [str(self.path)]
11651167

11661168
if template is not None:
1169+
if not isinstance(template, (str, pathlib.Path)):
1170+
msg = "template must be a string or Path"
1171+
raise TypeError(msg)
1172+
template_path = pathlib.Path(template)
1173+
if not template_path.is_dir():
1174+
msg = f"template directory does not exist: {template}"
1175+
raise ValueError(msg)
11671176
local_flags.append(f"--template={template}")
1177+
11681178
if separate_git_dir is not None:
11691179
if isinstance(separate_git_dir, pathlib.Path):
11701180
separate_git_dir = str(separate_git_dir.absolute())
11711181
local_flags.append(f"--separate-git-dir={separate_git_dir!s}")
1182+
11721183
if object_format is not None:
1184+
if object_format not in {"sha1", "sha256"}:
1185+
msg = "object_format must be either 'sha1' or 'sha256'"
1186+
raise ValueError(msg)
11731187
local_flags.append(f"--object-format={object_format}")
1174-
if branch is not None:
1175-
local_flags.extend(["--initial-branch", branch])
1176-
elif initial_branch is not None:
1177-
local_flags.extend(["--initial-branch", initial_branch])
1188+
1189+
if branch is not None and initial_branch is not None:
1190+
msg = "Cannot specify both branch and initial_branch"
1191+
raise ValueError(msg)
1192+
1193+
branch_name = branch or initial_branch
1194+
if branch_name is not None:
1195+
if any(c.isspace() for c in branch_name):
1196+
msg = "Branch name cannot contain whitespace"
1197+
raise ValueError(msg)
1198+
local_flags.extend(["--initial-branch", branch_name])
1199+
11781200
if shared is not None:
1201+
valid_shared_values = {
1202+
"false",
1203+
"true",
1204+
"umask",
1205+
"group",
1206+
"all",
1207+
"world",
1208+
"everybody",
1209+
}
11791210
if isinstance(shared, bool):
11801211
local_flags.append("--shared")
11811212
else:
1213+
shared_str = str(shared).lower()
1214+
# Check if it's a valid string value or an octal number
1215+
if not (
1216+
shared_str in valid_shared_values
1217+
or (
1218+
shared_str.isdigit()
1219+
and len(shared_str) <= 4
1220+
and all(c in string.octdigits for c in shared_str)
1221+
)
1222+
):
1223+
msg = (
1224+
f"Invalid shared value. Must be one of {valid_shared_values} "
1225+
"or an octal number"
1226+
)
1227+
raise ValueError(msg)
11821228
local_flags.append(f"--shared={shared}")
11831229
if quiet is True:
11841230
local_flags.append("--quiet")

0 commit comments

Comments
 (0)