Skip to content

Throw nicer error when git username or email are not configured #389

@flying-sheep

Description

@flying-sheep

# Check if git user.name and user.email are configured --> fail early if it's not set
run(["git", "config", "user.name"], check=True)
run(["git", "config", "user.email"], check=True)

> uvx --with pre-commit cruft create https://github.com/scverse/cookiecutter-scverse
  [1/9] Your project's name (project-name): …
  [2/9] If the Python package name differs from the project name, edit it now (…): 
  [3/9] A short one-line description of what your project does (A very interesting piece of code): …
  [4/9] Your complete name (Your Name): …
  [5/9] The e-mail address your package's users can contact you under ([email protected]): …
  [6/9] The GitHub username or org the project is to be published under (your_github_username): …
  [7/9] If the repo name should differ from the project name, edit it now (…): 
  [8/9] Select license
    1 - MIT License
    2 - BSD 2-Clause License
    3 - BSD 3-Clause License
    4 - Apache License Version 2.0
    5 - GNU General Public License Version 3
    6 - Unlicense
    Choose from [1/2/3/4/5/6] (1): 
  [9/9] Whether to generate IDE configuration files [y/n] (y): 
Traceback (most recent call last):
  File "/tmp/tmpcntxpzfv.py", line 6, in <module>
    run(["git", "config", "user.email"], check=True)
  File "…", line 526, in run
    raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['git', 'config', 'user.email']' returned non-zero exit status 1.
Stopping generation because pre_gen_project hook script didn't exit successfully
╭─────────────────────────────────────────────────────── Traceback (most recent call last) ───────────────────────────────────────────────────────╮
│ …/site-packages/cruft/_cli.py:115 in create                                                                                                     │
│                                                                                                                                                 │
│   112 │   │   None, "--skip", show_default=False, help="Default files/pattern to skip on updat                                                  │
│   113 │   ),                                                                                                                                    │
│   114 ) -> None:                                                                                                                                │
│ ❱ 115 │   _commands.create(                                                                                                                     │
│   116 │   │   template_git_url,                                                                                                                 │
│   117 │   │   output_dir=output_dir,                                                                                                            │
│   118 │   │   config_file=config_file,                                                                                                          │
│                                                                                                                                                 │
│ ╭──────────────────────────────── locals ─────────────────────────────────╮                                                                     │
│ │            checkout = None                                              │                                                                     │
│ │         config_file = None                                              │                                                                     │
│ │      default_config = False                                             │                                                                     │
│ │           directory = None                                              │                                                                     │
│ │       extra_context = '{}'                                              │                                                                     │
│ │  extra_context_file = None                                              │                                                                     │
│ │            no_input = False                                             │                                                                     │
│ │          output_dir = PosixPath('.')                                    │                                                                     │
│ │ overwrite_if_exists = False                                             │                                                                     │
│ │                skip = None                                              │                                                                     │
│ │    template_git_url = 'https://github.com/scverse/cookiecutter-scverse' │                                                                     │
│ ╰─────────────────────────────────────────────────────────────────────────╯                                                                     │
│                                                                                                                                                 │
│ …/site-packages/cruft/_commands/utils/__init__.py:14                                                                                            │
│ in wrapper                                                                                                                                      │
│                                                                                                                                                 │
│   11 │   │   def decorator(f):                                                                                                                  │
│   12 │   │   │   @wraps(f)                                                                                                                      │
│   13 │   │   │   def wrapper(*args, **kwargs):                                                                                                  │
│ ❱ 14 │   │   │   │   return f(*args, **kwargs)                                                                                                  │
│   15 │   │   │                                                                                                                                  │
│   16 │   │   │   return wrapper                                                                                                                 │
│   17                                                                                                                                            │
│                                                                                                                                                 │
│ ╭─────────────────────────── locals ────────────────────────────╮                                                                               │
│ │   args = ('https://github.com/scverse/cookiecutter-scverse',) │                                                                               │
│ │ kwargs = {                                                    │                                                                               │
│ │          │   'output_dir': PosixPath('.'),                    │                                                                               │
│ │          │   'config_file': None,                             │                                                                               │
│ │          │   'default_config': False,                         │                                                                               │
│ │          │   'extra_context': {},                             │                                                                               │
│ │          │   'extra_context_file': None,                      │                                                                               │
│ │          │   'no_input': False,                               │                                                                               │
│ │          │   'directory': None,                               │                                                                               │
│ │          │   'checkout': None,                                │                                                                               │
│ │          │   'overwrite_if_exists': False,                    │                                                                               │
│ │          │   'skip': None                                     │                                                                               │
│ │          }                                                    │                                                                               │
│ ╰───────────────────────────────────────────────────────────────╯                                                                               │
│                                                                                                                                                 │
│ …/site-packages/cruft/_commands/create.py:50 in                                                                                                 │
│ create                                                                                                                                          │
│                                                                                                                                                 │
│   47 │   │   │   )                                                                                                                              │
│   48 │   │                                                                                                                                      │
│   49 │   │   project_dir = Path(                                                                                                                │
│ ❱ 50 │   │   │   generate_files(                                                                                                                │
│   51 │   │   │   │   repo_dir=cookiecutter_template_dir,                                                                                        │
│   52 │   │   │   │   context=context,                                                                                                           │
│   53 │   │   │   │   overwrite_if_exists=overwrite_if_exists,                                                                                   │
│                                                                                                                                                 │
│ ╭────────────────────────────────────────────────────────────────── locals ───────────────────────────────────────────────────────────────────╮ │
│ │                      checkout = None                                                                                                        │ │
│ │                   config_file = None                                                                                                        │ │
│ │                       context = OrderedDict(…)                                                                                              │ │
│ │     cookiecutter_template_dir = PosixPath('/tmp/tmpqix81rpg')                                                                               │ │
│ │ cookiecutter_template_dir_str = '/tmp/tmpqix81rpg'                                                                                          │ │
│ │                default_config = False                                                                                                       │ │
│ │                     directory = None                                                                                                        │ │
│ │                 extra_context = {}                                                                                                          │ │
│ │            extra_context_file = None                                                                                                        │ │
│ │                   last_commit = '5af61043f3deaccb51b5956249dabeba7ab34480'                                                                  │ │
│ │                      no_input = False                                                                                                       │ │
│ │                    output_dir = PosixPath('.')                                                                                              │ │
│ │           overwrite_if_exists = False                                                                                                       │ │
│ │                          repo = <git.repo.base.Repo '/tmp/tmpqix81rpg/.git'>                                                                │ │
│ │                          skip = None                                                                                                        │ │
│ │              template_git_url = 'https://github.com/scverse/cookiecutter-scverse'                                                           │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                                                                                 │
│ …/site-packages/cookiecutter/generate.py:342 in                                                                                                 │
│ generate_files                                                                                                                                  │
│                                                                                                                                                 │
│   339 │   delete_project_on_failure = output_directory_created and not keep_project_on_failure                                                  │
│   340 │                                                                                                                                         │
│   341 │   if accept_hooks:                                                                                                                      │
│ ❱ 342 │   │   run_hook_from_repo_dir(                                                                                                           │
│   343 │   │   │   repo_dir, 'pre_gen_project', project_dir, context, delete_project_on_failure                                                  │
│   344 │   │   )                                                                                                                                 │
│   345                                                                                                                                           │
│                                                                                                                                                 │
│ ╭────────────────────────────────────────────────────────────────── locals ───────────────────────────────────────────────────────────────────╮ │
│ │              accept_hooks = True                                                                                                            │ │
│ │                   context = OrderedDict(…)                                                                                                  │ │
│ │ delete_project_on_failure = True                                                                                                            │ │
│ │                       env = <cookiecutter.environment.StrictEnvironment object at 0x7f7c9a6f3b80>                                           │ │
│ │   keep_project_on_failure = False                                                                                                           │ │
│ │                output_dir = '.'                                                                                                             │ │
│ │  output_directory_created = True                                                                                                            │ │
│ │       overwrite_if_exists = False                                                                                                           │ │
│ │               project_dir = '…'                                                                                                             │ │
│ │                  repo_dir = PosixPath('/tmp/tmpqix81rpg')                                                                                   │ │
│ │       skip_if_file_exists = False                                                                                                           │ │
│ │              template_dir = PosixPath('/tmp/tmpqix81rpg/{{cookiecutter.project_name}}')                                                     │ │
│ │            unrendered_dir = '{{cookiecutter.project_name}}'                                                                                 │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                                                                                 │
│ …/site-packages/cookiecutter/hooks.py:157 in run_hook_from_repo_dir                                                                             │
│                                                                                                                                                 │
│   154 │   """                                                                                                                                   │
│   155 │   with work_in(repo_dir):                                                                                                               │
│   156 │   │   try:                                                                                                                              │
│ ❱ 157 │   │   │   run_hook(hook_name, project_dir, context)                                                                                     │
│   158 │   │   except (                                                                                                                          │
│   159 │   │   │   FailedHookException,                                                                                                          │
│   160 │   │   │   UndefinedError,                                                                                                               │
│                                                                                                                                                 │
│ ╭────────────────────────────────────────────────────────────────── locals ───────────────────────────────────────────────────────────────────╮ │
│ │                   context = OrderedDict(…)                                                                                                  │ │
│ │ delete_project_on_failure = True                                                                                                            │ │
│ │                 hook_name = 'pre_gen_project'                                                                                               │ │
│ │               project_dir = '…'                                                                                                             │ │
│ │                  repo_dir = PosixPath('/tmp/tmpqix81rpg')                                                                                   │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                                                                                 │
│ …/site-packages/cookiecutter/hooks.py:140 in run_hook                                                                                           │
│                                                                                                                                                 │
│   137 │   │   return                                                                                                                            │
│   138 │   logger.debug('Running hook %s', hook_name)                                                                                            │
│   139 │   for script in scripts:                                                                                                                │
│ ❱ 140 │   │   run_script_with_context(script, project_dir, context)                                                                             │
│   141                                                                                                                                           │
│   142                                                                                                                                           │
│   143 def run_hook_from_repo_dir(                                                                                                               │
│                                                                                                                                                 │
│ ╭────────────────────────────────────────────────────────────────── locals ───────────────────────────────────────────────────────────────────╮ │
│ │     context = OrderedDict(…)                                                                                                                │ │
│ │   hook_name = 'pre_gen_project'                                                                                                             │ │
│ │ project_dir = '…'                                                                                                                           │ │
│ │      script = '/tmp/tmpqix81rpg/hooks/pre_gen_project.py'                                                                                   │ │
│ │     scripts = ['/tmp/tmpqix81rpg/hooks/pre_gen_project.py']                                                                                 │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                                                                                 │
│ ~/.cache/uv/archive-v0/C6_QdJ84lVFMpdo0L9J23/lib/python3.10/site-packages/cookiecutter/hooks.py:123 in                                          │
│ run_script_with_context                                                                                                                         │
│                                                                                                                                                 │
│   120 │   │   output = template.render(**context)                                                                                               │
│   121 │   │   temp.write(output.encode('utf-8'))                                                                                                │
│   122 │                                                                                                                                         │
│ ❱ 123 │   run_script(temp.name, cwd)                                                                                                            │
│   124                                                                                                                                           │
│   125                                                                                                                                           │
│   126 def run_hook(hook_name, project_dir, context):                                                                                            │
│                                                                                                                                                 │
│ ╭────────────────────────────────────────────────────────────────── locals ───────────────────────────────────────────────────────────────────╮ │
│ │           _ = '/tmp/tmpqix81rpg/hooks/pre_gen_project'                                                                                      │ │
│ │    contents = '#!/bin/env python3\nfrom subprocess import run\n\n# Check if git user.name and user'+279                                     │ │
│ │     context = OrderedDict(…)                                                                                                                │ │
│ │         cwd = '~'                                                                                                                           │ │
│ │         env = <cookiecutter.environment.StrictEnvironment object at 0x7f7c9a6f3a30>                                                         │ │
│ │   extension = '.py'                                                                                                                         │ │
│ │        file = <_io.TextIOWrapper name='/tmp/tmpqix81rpg/hooks/pre_gen_project.py' mode='r' encoding='utf-8'>                                │ │
│ │      output = '#!/bin/env python3\nfrom subprocess import run\n\n# Check if git user.name and user'+279                                     │ │
│ │ script_path = '/tmp/tmpqix81rpg/hooks/pre_gen_project.py'                                                                                   │ │
│ │        temp = <tempfile._TemporaryFileWrapper object at 0x7f7c9a1eb5e0>                                                                     │ │
│ │    template = <Template memory:7f7c9a6f32b0>                                                                                                │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                                                                                 │
│ ~/site-packages/cookiecutter/hooks.py:94 in           │
│ run_script                                                                                                                                      │
│                                                                                                                                                 │
│    91 │   │   proc = subprocess.Popen(script_command, shell=run_thru_shell, cwd=cwd)  # nosec                                                   │
│    92 │   │   exit_status = proc.wait()                                                                                                         │
│    93 │   │   if exit_status != EXIT_SUCCESS:                                                                                                   │
│ ❱  94 │   │   │   raise FailedHookException(                                                                                                    │
│    95 │   │   │   │   f'Hook script failed (exit status: {exit_status})'                                                                        │
│    96 │   │   │   )                                                                                                                             │
│    97 │   except OSError as err:                                                                                                                │
│                                                                                                                                                 │
│ ╭──────────────────────────────────────────────────────────── locals ────────────────────────────────────────────────────────────╮              │
│ │            cwd = '~'                                                                                                           │              │
│ │    exit_status = 1                                                                                                             │              │
│ │           proc = <Popen: returncode: 1 args: ['~']>                                                                            │              │
│ │ run_thru_shell = False                                                                                                         │              │
│ │ script_command = ['~/.cache/uv/archive-v0/C6_QdJ84lVFMpdo0L9J23/bin'+7, '/tmp/tmpcntxpzfv.py']                                 │              │
│ │    script_path = '/tmp/tmpcntxpzfv.py'                                                                                         │              │
│ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯              │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
FailedHookException: Hook script failed (exit status: 1)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions