Skip to content

Commit 910c350

Browse files
authored
feat: initialize git repository when running pdm init (#3483)
Signed-off-by: Frost Ming <[email protected]>
1 parent b6355f1 commit 910c350

File tree

6 files changed

+71
-6
lines changed

6 files changed

+71
-6
lines changed

src/pdm/cli/commands/init.py

+33
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,32 @@ class Command(BaseCommand):
3636
def __init__(self) -> None:
3737
self.interactive = True
3838

39+
def initialize_git(self, project: Project) -> None:
40+
"""Initialize a git repository if git is available and .git doesn't exist."""
41+
import shutil
42+
import subprocess
43+
44+
if (project.root / ".git").exists():
45+
project.core.ui.info("Git repository already exists, skipping initialization.")
46+
return
47+
48+
git_command = shutil.which("git")
49+
if not git_command:
50+
project.core.ui.info("Git command not found, skipping initialization.")
51+
return
52+
53+
try:
54+
subprocess.run(
55+
[git_command, "init"],
56+
cwd=project.root,
57+
check=True,
58+
capture_output=True,
59+
encoding="utf-8",
60+
)
61+
project.core.ui.info("Git repository initialized successfully.")
62+
except subprocess.CalledProcessError as e:
63+
project.core.ui.error(f"Failed to initialize Git repository: {e.stderr}")
64+
3965
def do_init(self, project: Project, options: argparse.Namespace) -> None:
4066
"""Bootstrap the project and create a pyproject.toml"""
4167
hooks = HookManager(project, options.skip)
@@ -46,6 +72,10 @@ def do_init(self, project: Project, options: argparse.Namespace) -> None:
4672
else:
4773
self.set_python(project, options.python, hooks)
4874
self._init_builtin(project, options)
75+
76+
if options.init_git:
77+
self.initialize_git(project)
78+
4979
hooks.try_emit("post_init")
5080

5181
def _init_copier(self, project: Project, options: argparse.Namespace) -> None:
@@ -221,6 +251,9 @@ def add_arguments(self, parser: argparse.ArgumentParser) -> None:
221251
group.add_argument("--license", help="Specify the license (SPDX name)")
222252
group.add_argument("--name", help="Specify the project name")
223253
group.add_argument("--project-version", help="Specify the project's version")
254+
group.add_argument(
255+
"--no-git", dest="init_git", action="store_false", default=True, help="Do not initialize a git repository"
256+
)
224257
parser.add_argument(
225258
"template", nargs="?", help="Specify the project template, which can be a local path or a Git URL"
226259
)

src/pdm/cli/completions/pdm.bash

+6-2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ _pdm_a919b69078acdf0a_complete()
6565
;;
6666

6767
(init)
68-
opts="--backend --cookiecutter --copier --dist --global --help --license --non-interactive --overwrite --project --project-version --python --quiet --skip --verbose"
68+
opts="--backend --cookiecutter --copier --dist --global --help --license --name --no-git --non-interactive --overwrite --project --project-version --python --quiet --skip --verbose"
6969
;;
7070

7171
(install)
@@ -80,6 +80,10 @@ _pdm_a919b69078acdf0a_complete()
8080
opts="--append --check --config-setting --dev --exclude-newer --global --group --help --implementation --lockfile --no-cross-platform --no-default --no-isolation --no-static-urls --override --platform --production --project --python --quiet --refresh --skip --static-urls --strategy --update-reuse --update-reuse-installed --verbose --without"
8181
;;
8282

83+
(new)
84+
opts="--backend --dist --help --license --name --no-git --non-interactive --overwrite --project-version --python --quiet --skip --verbose"
85+
;;
86+
8387
(outdated)
8488
opts="--global --help --include-sub --json --project --quiet --verbose"
8589
;;
@@ -146,7 +150,7 @@ _pdm_a919b69078acdf0a_complete()
146150

147151
# completing for a command
148152
if [[ $cur == $com ]]; then
149-
coms="add build cache completion config export fix import info init install list lock outdated plugin publish py python remove run search self show sync update use venv"
153+
coms="add build cache completion config export fix import info init install list lock new outdated plugin publish py python remove run search self show sync update use venv"
150154

151155
COMPREPLY=($(compgen -W "${coms}" -- ${cur}))
152156
__ltrim_colon_completions "$cur"

src/pdm/cli/completions/pdm.fish

+20-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
function __fish_pdm_a919b69078acdf0a_complete_no_subcommand
55
for i in (commandline -opc)
6-
if contains -- $i add build cache completion config export fix import info init install list lock outdated plugin publish py python remove run search self show sync update use venv
6+
if contains -- $i add build cache completion config export fix import info init install list lock new outdated plugin publish py python remove run search self show sync update use venv
77
return 1
88
end
99
end
@@ -122,7 +122,7 @@ complete -c pdm -f -n '__fish_pdm_a919b69078acdf0a_complete_no_subcommand' -a ex
122122
complete -c pdm -A -n '__fish_seen_subcommand_from export' -l dev -d 'Select dev dependencies'
123123
complete -c pdm -A -n '__fish_seen_subcommand_from export' -l editable-self -d 'Include the project itself as an editable dependency'
124124
complete -c pdm -A -n '__fish_seen_subcommand_from export' -l expandvars -d 'Expand environment variables in requirements'
125-
complete -c pdm -A -n '__fish_seen_subcommand_from export' -l format -d 'Only requirements.txt is supported for now.'
125+
complete -c pdm -A -n '__fish_seen_subcommand_from export' -l format -d 'Export to requirements.txt format or pylock.toml format'
126126
complete -c pdm -A -n '__fish_seen_subcommand_from export' -l global -d 'Use the global project, supply the project root with `-p` option'
127127
complete -c pdm -A -n '__fish_seen_subcommand_from export' -l group -d 'Select group of optional-dependencies separated by comma or dependency-groups (with `-d`). Can be supplied multiple times, use ":all" to include all groups under the same species.'
128128
complete -c pdm -A -n '__fish_seen_subcommand_from export' -l help -d 'Show this help message and exit.'
@@ -188,6 +188,8 @@ complete -c pdm -A -n '__fish_seen_subcommand_from init' -l dist -d 'Create a pa
188188
complete -c pdm -A -n '__fish_seen_subcommand_from init' -l global -d 'Use the global project, supply the project root with `-p` option'
189189
complete -c pdm -A -n '__fish_seen_subcommand_from init' -l help -d 'Show this help message and exit.'
190190
complete -c pdm -A -n '__fish_seen_subcommand_from init' -l license -d 'Specify the license (SPDX name)'
191+
complete -c pdm -A -n '__fish_seen_subcommand_from init' -l name -d 'Specify the project name'
192+
complete -c pdm -A -n '__fish_seen_subcommand_from init' -l no-git -d 'Do not initialize a git repository'
191193
complete -c pdm -A -n '__fish_seen_subcommand_from init' -l non-interactive -d 'Don\'t ask questions but use default values'
192194
complete -c pdm -A -n '__fish_seen_subcommand_from init' -l overwrite -d 'Overwrite existing files'
193195
complete -c pdm -A -n '__fish_seen_subcommand_from init' -l project -d 'Specify another path as the project root, which changes the base of pyproject.toml and __pypackages__ [env var: PDM_PROJECT]'
@@ -274,6 +276,22 @@ complete -c pdm -A -n '__fish_seen_subcommand_from lock' -l update-reuse-install
274276
complete -c pdm -A -n '__fish_seen_subcommand_from lock' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed'
275277
complete -c pdm -A -n '__fish_seen_subcommand_from lock' -l without -d 'Exclude groups of optional-dependencies or dependency-groups'
276278

279+
# new
280+
complete -c pdm -f -n '__fish_pdm_a919b69078acdf0a_complete_no_subcommand' -a new -d 'Create a new Python project at <project_path>'
281+
complete -c pdm -A -n '__fish_seen_subcommand_from new' -l backend -d 'Specify the build backend, which implies --dist'
282+
complete -c pdm -A -n '__fish_seen_subcommand_from new' -l dist -d 'Create a package for distribution'
283+
complete -c pdm -A -n '__fish_seen_subcommand_from new' -l help -d 'Show this help message and exit.'
284+
complete -c pdm -A -n '__fish_seen_subcommand_from new' -l license -d 'Specify the license (SPDX name)'
285+
complete -c pdm -A -n '__fish_seen_subcommand_from new' -l name -d 'Specify the project name'
286+
complete -c pdm -A -n '__fish_seen_subcommand_from new' -l no-git -d 'Do not initialize a git repository'
287+
complete -c pdm -A -n '__fish_seen_subcommand_from new' -l non-interactive -d 'Don\'t ask questions but use default values'
288+
complete -c pdm -A -n '__fish_seen_subcommand_from new' -l overwrite -d 'Overwrite existing files'
289+
complete -c pdm -A -n '__fish_seen_subcommand_from new' -l project-version -d 'Specify the project\'s version'
290+
complete -c pdm -A -n '__fish_seen_subcommand_from new' -l python -d 'Specify the Python version/path to use'
291+
complete -c pdm -A -n '__fish_seen_subcommand_from new' -l quiet -d 'Suppress output'
292+
complete -c pdm -A -n '__fish_seen_subcommand_from new' -l skip -d 'Skip some tasks and/or hooks by their comma-separated names. Can be supplied multiple times. Use ":all" to skip all hooks. Use ":pre" and ":post" to skip all pre or post hooks.'
293+
complete -c pdm -A -n '__fish_seen_subcommand_from new' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed'
294+
277295
# outdated
278296
complete -c pdm -f -n '__fish_pdm_a919b69078acdf0a_complete_no_subcommand' -a outdated -d 'Check for outdated packages and list the latest versions on indexes.'
279297
complete -c pdm -A -n '__fish_seen_subcommand_from outdated' -l global -d 'Use the global project, supply the project root with `-p` option'

src/pdm/cli/completions/pdm.ps1

+2-1
Original file line numberDiff line numberDiff line change
@@ -286,12 +286,13 @@ function TabExpansion($line, $lastWord) {
286286
))
287287
break
288288
}
289+
"new" {}
289290
"init" {
290291
$completer.AddOpts(
291292
@(
292293
[Option]::new(@(
293294
"-g", "--global", "--non-interactive", "-n", "--python", "--dist", "--lib", "--copier",
294-
"--cookiecutter", "--overwrite", "--license", "--project-version"
295+
"--cookiecutter", "--overwrite", "--license", "--project-version", "--name", "--no-git"
295296
)),
296297
$projectOption,
297298
$skipOption,

src/pdm/cli/completions/pdm.zsh

+4-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ _pdm() {
2525
'import:Import project metadata from other formats'
2626
'info:Show the project information'
2727
'init:Initialize a pyproject.toml for PDM'
28+
'new:Create a new Python project at project_path'
2829
'install:Install dependencies from lock file'
2930
'list:List packages installed in the current working set'
3031
'lock:Resolve and lock dependencies'
@@ -195,7 +196,7 @@ _pdm() {
195196
'--venv[Run the command in the virtual environment with the given key. \[env var: PDM_IN_VENV\]]:venv:'
196197
)
197198
;;
198-
init)
199+
new|init)
199200
arguments+=(
200201
{-g,--global}'[Use the global project, supply the project root with `-p` option]'
201202
{-n,--non-interactive}"[Don't ask questions but use default values]"
@@ -207,6 +208,8 @@ _pdm() {
207208
'--copier[Use Copier to generate project]'
208209
'--cookiecutter[Use Cookiecutter to generate project]'
209210
'--license[Specify the license (SPDX name)]:license:'
211+
'--name[Specify the project name]:name:'
212+
'--no-git[Do not initialize a git repository]'
210213
"--project-version[Specify the project's version]:project_version:"
211214
'1:template:'
212215
)
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.py[cod]
2+
__pycache__/
3+
.mypy_cache/
4+
.pytest_cache/
5+
.ruff_cache/
6+
.pdm-python

0 commit comments

Comments
 (0)