Skip to content

Commit fb986b6

Browse files
Add --allow-nested flag to permit nested dummy repos and refactor tangential code
Signed-off-by: Jacob Stopak <jacob@initialcommit.io>
1 parent 79f963f commit fb986b6

File tree

4 files changed

+69
-15
lines changed

4 files changed

+69
-15
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ Available options and flags include:
6666
`--merge`: A comma separated list of branch postfix ids to merge back into `main`.
6767
`--git-dir`: The path at which to store the dummy Git repo, defaults to current directory.
6868
`--no-subdir`: Initialize the dummy Git repo in the current directory instead of in a subdirectory.
69-
`--constant_sha`: Use constant values for commit author, email, and commit date parameters to yield consistent sha1 values across git-dummy runs.
69+
`--constant_sha`: Use constant values for commit author, email, and commit date parameters to yield consistent sha1 values across git-dummy runs.
70+
`--allow-nested`: Allow dummy repo creation within an existing Git repo, as long as it's not at the level of an existing .git/ folder.
7071

7172
## Command examples
7273
Generate a dummy Git repo called "cheese" on your Desktop, with 2 branches and 10 commits on each branch:

git_dummy/__main__.py

+22-14
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
import sys
77

88
from git_dummy.settings import settings
9+
from git_dummy.util import (
10+
is_dir_exist,
11+
is_git_dir,
12+
is_inside_git_dir,
13+
is_valid_folder_name,
14+
)
915

1016

1117
app = typer.Typer(context_settings={"help_option_names": ["-h", "--help"]})
@@ -16,6 +22,7 @@ def main(
1622
name: str = typer.Option(
1723
settings.name,
1824
help="Name of the dummy repo",
25+
callback=is_valid_folder_name,
1926
),
2027
git_dir: pathlib.Path = typer.Option(
2128
settings.git_dir,
@@ -45,6 +52,10 @@ def main(
4552
settings.constant_sha,
4653
help="Use constant values for commit author, email, and commit date parameters to yield consistent sha1 values across git-dummy runs",
4754
),
55+
allow_nested: bool = typer.Option(
56+
settings.allow_nested,
57+
help="Allow dummy repo creation within an existing Git repo, as long as it's not at the level of an existing .git/ folder",
58+
),
4859
):
4960
settings.name = name
5061
settings.commits = commits
@@ -53,28 +64,25 @@ def main(
5364
settings.merge = merge
5465
settings.no_subdir = no_subdir
5566
settings.constant_sha = constant_sha
67+
settings.allow_nested = allow_nested
5668

5769
settings.git_dir = os.path.expanduser(git_dir)
5870
if not settings.no_subdir:
5971
settings.git_dir = os.path.join(settings.git_dir, settings.name)
6072

61-
try:
62-
git.Repo(settings.git_dir, search_parent_directories=True)
73+
if is_git_dir(settings.git_dir):
74+
print(f"git-dummy error: Git repository already exists at {settings.git_dir}")
75+
sys.exit(1)
76+
77+
if not settings.allow_nested and is_inside_git_dir(settings.git_dir):
6378
print(
64-
f"git-dummy error: Git repository already exists at {settings.git_dir} or parent"
79+
f"git-dummy error: Git repository already exists at {settings.git_dir} or parent: use --allow-nested flag to override"
6580
)
6681
sys.exit(1)
67-
except (git.exc.InvalidGitRepositoryError, git.exc.NoSuchPathError):
68-
try:
69-
git.Repo(pathlib.Path().cwd(), search_parent_directories=True)
70-
print(
71-
f"git-dummy error: Git repository already exists at {settings.git_dir} or parent"
72-
)
73-
sys.exit(1)
74-
except git.exc.InvalidGitRepositoryError:
75-
print(
76-
f"git-dummy: Generating dummy Git repo at {settings.git_dir} with {settings.branches} branch(es) and {settings.commits} commit(s)."
77-
)
82+
83+
print(
84+
f"git-dummy: Generating dummy Git repo at {settings.git_dir} with {settings.branches} branch(es) and {settings.commits} commit(s)."
85+
)
7886

7987
repo = git.Repo.init(settings.git_dir, initial_branch="main")
8088

git_dummy/settings.py

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ class Settings(BaseSettings):
1111
merge: str = ""
1212
no_subdir: bool = False
1313
constant_sha: bool = False
14+
allow_nested: bool = False
1415

1516
class Config:
1617
env_prefix = "git_dummy_"

git_dummy/util.py

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import git
2+
import os
3+
import typer
4+
5+
6+
def is_dir_exist(path):
7+
if os.path.exists(path) and os.path.isdir(path):
8+
return True
9+
return False
10+
11+
12+
def is_git_dir(path):
13+
try:
14+
git.Repo(path)
15+
return True
16+
except (git.exc.InvalidGitRepositoryError, git.exc.NoSuchPathError):
17+
return False
18+
19+
20+
def is_inside_git_dir(path):
21+
while not is_dir_exist(path):
22+
try:
23+
git.Repo(path, search_parent_directories=True)
24+
return True
25+
except (git.exc.InvalidGitRepositoryError, git.exc.NoSuchPathError):
26+
path = os.path.dirname(path)
27+
else:
28+
try:
29+
git.Repo(path, search_parent_directories=True)
30+
return True
31+
except (git.exc.InvalidGitRepositoryError, git.exc.NoSuchPathError):
32+
return False
33+
34+
35+
def is_valid_folder_name(name):
36+
allowed_characters = (
37+
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"
38+
)
39+
is_valid = all(char in set(allowed_characters) for char in name)
40+
if not is_valid:
41+
raise typer.BadParameter(
42+
f"only the following characters are permitted in the directory name: {allowed_characters}"
43+
)
44+
return name

0 commit comments

Comments
 (0)