Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Cannot run cruft update with emojis in pyproject.toml #284

Open
jjfantini opened this issue Feb 1, 2024 · 0 comments
Open

[BUG] Cannot run cruft update with emojis in pyproject.toml #284

jjfantini opened this issue Feb 1, 2024 · 0 comments

Comments

@jjfantini
Copy link

I have a pyproject.toml that has emojis in it to define custom commit logic with cz_customizable. However, cruft uses the wrong encoding for the pyproject.toml file, so I get an error when trying to run cruft update in that file. I can remove the emojis and then the command runs successfully.

Here is my pyproject.toml:

[build-system]  # https://python-poetry.org/docs/pyproject/#poetry-and-pep-517
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"


[tool.poetry]  # https://python-poetry.org/docs/pyproject/
name = "gitmoji-test"
version = "0.11.4"
description = "tests the use case of a gitmoji commit rule"
authors = ["Jennings Fantini <jjman2811@gmail.com>"]
readme = "README.md"
repository = "https://github.com/jjfantini/gitmoji-test"

[tool.cruft]
skip = ["menv/", "tests"]

[tool.commitizen]
name = "cz_gitmoji"
version = "0.11.4"
tag_format = "v$version"
update_changelog_on_bump = true
annotated_tag = true
major_version_zero = true
version_files = [
    "pyproject.toml:^version",
]
path = ".cz-config.js"

[tool.commitizen.customize]
example = "feat: this feature enables customizing through pyproject.toml file"
schema = """
<type>(<scope>): <subject> \n
<BLANK LINE> \n
<body> \n
<BLANK LINE> \n
(BREAKING CHANGE: )<breaking> \n
<BLANK LINE> \n
(ISSUES: )<footer>
"""
schema_pattern = "(?s)(✨ feat|🐛 fix|🚑 hotfix|🔧 chore|♻️ refactor|🚧 WIP|📚 docs|⚡️ perf|💄 style|🏗️ build|👷 ci|✅ test|⏪ revert|➕ add_dep|➖ rem_dep)(\\(\\S+\\))?!?:( [^\\n\\r]+)((\\n\\n.*)|(\\s*))?$"
bump_pattern = "^(✨ feat|🐛 fix|🚑 hotfix|⚡️ perf|♻️ refactor|⏪ revert|➕ add_dep)"

Here is my error:

 cruft update
[04:43:19] INFO     Running post_gen_project hook...                                                               tmp2lqou4k3.py:20
[04:43:20] INFO     Attempting Micromamba installation...                                                         tmp2lqou4k3.py:162
[04:43:21] WARNING  [WinError 5] Access is denied: 'C:\\Users\\jjfan\\Application Data'                           tmp2lqou4k3.py:144
           WARNING  [WinError 5] Access is denied: 'C:\\Users\\jjfan\\Cookies'                                    tmp2lqou4k3.py:144
           WARNING  [WinError 5] Access is denied: 'C:\\Users\\jjfan\\Documents\\My Music'                        tmp2lqou4k3.py:144
           WARNING  [WinError 5] Access is denied: 'C:\\Users\\jjfan\\Documents\\My Videos'                       tmp2lqou4k3.py:144
A micromamba menv existed: C:\Users\jjfan\github\gitmoji-test\menv
[04:43:22] INFO     Finished!                                                                                     tmp2lqou4k3.py:189
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ C:\Users\jjfan\github\gitmoji-test\menv\Lib\site-packages\cruft\_cli.py:273 in update            │
│                                                                                                  │
│   270 │   │   readable=True,                                                                     │
│   271 │   ),                                                                                     │
│   272 ) -> None:                                                                                 │
│ ❱ 273 │   if not _commands.update(                                                               │
│   274 │   │   project_dir=project_dir,                                                           │
│   275 │   │   cookiecutter_input=cookiecutter_input,                                             │
│   276 │   │   refresh_private_variables=refresh_private_variables,                               │
│                                                                                                  │
│ ╭─────────────────── locals ───────────────────╮                                                 │
│ │     allow_untracked_files = False            │                                                 │
│ │                  checkout = None             │                                                 │
│ │        cookiecutter_input = False            │                                                 │
│ │             extra_context = '{}'             │                                                 │
│ │        extra_context_file = None             │                                                 │
│ │               project_dir = WindowsPath('.') │                                                 │
│ │ refresh_private_variables = False            │                                                 │
│ │            skip_apply_ask = False            │                                                 │
│ │               skip_update = False            │                                                 │
│ │                    strict = True             │                                                 │
│ ╰──────────────────────────────────────────────╯                                                 │
│                                                                                                  │
│ C:\Users\jjfan\github\gitmoji-test\menv\Lib\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 = ()                                      │                                             │
│ │      f = <function update at 0x000001D35F97B600> │                                             │
│ │ kwargs = {                                       │                                             │
│ │          │   'project_dir': WindowsPath('.'),    │                                             │
│ │          │   'cookiecutter_input': False,        │                                             │
│ │          │   'refresh_private_variables': False, │                                             │
│ │          │   'skip_apply_ask': False,            │                                             │
│ │          │   'skip_update': False,               │                                             │
│ │          │   'checkout': None,                   │                                             │
│ │          │   'strict': True,                     │                                             │
│ │          │   'allow_untracked_files': False,     │                                             │
│ │          │   'extra_context': {},                │                                             │
│ │          │   'extra_context_file': None          │                                             │
│ │          }                                       │                                             │
│ ╰──────────────────────────────────────────────────╯                                             │
│                                                                                                  │
│ C:\Users\jjfan\github\gitmoji-test\menv\Lib\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 = ()                                      │                                             │
│ │      f = <function update at 0x000001D35F97B560> │                                             │
│ │ kwargs = {                                       │                                             │
│ │          │   'project_dir': WindowsPath('.'),    │                                             │
│ │          │   'cookiecutter_input': False,        │                                             │
│ │          │   'refresh_private_variables': False, │                                             │
│ │          │   'skip_apply_ask': False,            │                                             │
│ │          │   'skip_update': False,               │                                             │
│ │          │   'checkout': None,                   │                                             │
│ │          │   'strict': True,                     │                                             │
│ │          │   'allow_untracked_files': False,     │                                             │
│ │          │   'extra_context': {},                │                                             │
│ │          │   'extra_context_file': None          │                                             │
│ │          }                                       │                                             │
│ ╰──────────────────────────────────────────────────╯                                             │
│                                                                                                  │
│ C:\Users\jjfan\github\gitmoji-test\menv\Lib\site-packages\cruft\_commands\update.py:96 in update │
│                                                                                                  │
│    93 │   │   │   # cookiecutter.                                                                │
│    94 │   │   │   # For the current cruft state, we do not try to update the cookiecutter_inpu   │
│    95 │   │   │   # because we want to keep the current context input intact.                    │
│ ❱  96 │   │   │   _ = utils.generate.cookiecutter_template(                                      │
│    97 │   │   │   │   output_dir=current_template_dir,                                           │
│    98 │   │   │   │   repo=repo,                                                                 │
│    99 │   │   │   │   cruft_state=cruft_state,                                                   │
│                                                                                                  │
│ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │
│ │     allow_untracked_files = False                                                            │ │
│ │                  checkout = None                                                             │ │
│ │        cookiecutter_input = False                                                            │ │
│ │                cruft_file = WindowsPath('.cruft.json')                                       │ │
│ │               cruft_state = {                                                                │ │
│ │                             │   'template':                                                  │ │
│ │                             'https://github.com/humblFINANCE/cookiecutter-python',           │ │
│ │                             │   'commit': 'd3f580ed7315f1cb472a354475c0de59de3b4730',        │ │
│ │                             │   'checkout': None,                                            │ │
│ │                             │   'context': {                                                 │ │
│ │                             │   │   'cookiecutter': {                                        │ │
│ │                             │   │   │   'package_name': 'gitmoji-test',                      │ │
│ │                             │   │   │   'package_description': 'tests the use case of a      │ │
│ │                             gitmoji commit rule',                                            │ │
│ │                             │   │   │   'package_url':                                       │ │
│ │                             'https://github.com/jjfantini/gitmoji-test',                     │ │
│ │                             │   │   │   'author_name': 'Jennings Fantini',                   │ │
│ │                             │   │   │   'author_email': 'jjman2811@gmail.com',               │ │
│ │                             │   │   │   'github_username': 'jjfantini',                      │ │
│ │                             │   │   │   'python_version': '3.12.1',                          │ │
│ │                             │   │   │   'docker_image': 'python:3.12.1-slim',                │ │
│ │                             │   │   │   'development_environment': 'strict',                 │ │
│ │                             │   │   │   'with_conventional_commits': '1',                    │ │
│ │                             │   │   │   ... +16                                              │ │
│ │                             │   │   }                                                        │ │
│ │                             │   },                                                           │ │
│ │                             │   'directory': None                                            │ │
│ │                             }                                                                │ │
│ │      current_template_dir = WindowsPath('C:/Users/jjfan/AppData/Local/Temp/tmp_bidubym/curr… │ │
│ │             deleted_paths = set()                                                            │ │
│ │                 directory = 'repo'                                                           │ │
│ │             extra_context = {}                                                               │ │
│ │        extra_context_file = None                                                             │ │
│ │               last_commit = 'd1a7b2fe78be83aacce781547f655bf31356ede3'                       │ │
│ │          new_template_dir = WindowsPath('C:/Users/jjfan/AppData/Local/Temp/tmp_bidubym/new_… │ │
│ │               project_dir = WindowsPath('.')                                                 │ │
│ │ refresh_private_variables = False                                                            │ │
│ │                      repo = <git.repo.base.Repo                                              │ │
│ │                             'C:\\Users\\jjfan\\AppData\\Local\\Temp\\tmp_bidubym\\repo\\.gi… │ │
│ │                  repo_dir = WindowsPath('C:/Users/jjfan/AppData/Local/Temp/tmp_bidubym/repo… │ │
│ │            skip_apply_ask = False                                                            │ │
│ │               skip_update = False                                                            │ │
│ │                    strict = True                                                             │ │
│ │                    tmpdir = WindowsPath('C:/Users/jjfan/AppData/Local/Temp/tmp_bidubym')     │ │
│ │                   tmpdir_ = 'C:\\Users\\jjfan\\AppData\\Local\\Temp\\tmp_bidubym'            │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                                  │
│ C:\Users\jjfan\github\gitmoji-test\menv\Lib\site-packages\cruft\_commands\utils\generate.py:47   │
│ in cookiecutter_template                                                                         │
│                                                                                                  │
│    44 │   context = _generate_output(cruft_state, Path(repo.working_dir), cookiecutter_input,    │
│    45 │                                                                                          │
│    46 │   # Get all paths that we are supposed to skip before generating the diff and applying   │
│ ❱  47 │   skip_paths = _get_skip_paths(cruft_state, pyproject_file)                              │
│    48 │   # We also get the list of paths that were deleted from the project                     │
│    49 │   # directory but were present in the template that the project is linked against        │
│    50 │   # This is to avoid introducing changes that won't apply cleanly to the current proje   │
│                                                                                                  │
│ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │
│ │             checkout = 'd3f580ed7315f1cb472a354475c0de59de3b4730'                            │ │
│ │               commit = 'd3f580ed7315f1cb472a354475c0de59de3b4730'                            │ │
│ │              context = OrderedDict({'cookiecutter': OrderedDict({'package_name':             │ │
│ │                        'gitmoji-test', 'package_description': 'tests the use case of a       │ │
│ │                        gitmoji commit rule', 'package_url':                                  │ │
│ │                        'https://github.com/jjfantini/gitmoji-test', 'author_name': 'Jennings │ │
│ │                        Fantini', 'author_email': 'jjman2811@gmail.com', 'github_username':   │ │
│ │                        'jjfantini', 'python_version': '3.12.1', 'docker_image':              │ │
│ │                        'python:3.12.1-slim', 'development_environment': 'strict',            │ │
│ │                        'with_conventional_commits': '1', 'with_micromamba': '1',             │ │
│ │                        'with_fastapi_api': '0', 'with_streamlit_app': '0', 'with_typer_cli': │ │
│ │                        '0', 'with_jupyter_lab': '1', 'with_pydantic_typing': '1',            │ │
│ │                        'with_pandera_models': '1', 'with_sentry_logging': '1',               │ │
│ │                        'continuous_integration': 'GitHub', 'documentation_tool': 'sphinx',   │ │
│ │                        'docstring_style': 'NumPy', 'private_package_repository_name': '',    │ │
│ │                        'private_package_repository_url': '', '__package_name_kebab_case':    │ │
│ │                        'gitmoji-test', '__package_name_snake_case': 'gitmoji_test',          │ │
│ │                        '_template':                                                          │ │
│ │                        'https://github.com/humblFINANCE/cookiecutter-python'})})             │ │
│ │   cookiecutter_input = False                                                                 │ │
│ │          cruft_state = {                                                                     │ │
│ │                        │   'template':                                                       │ │
│ │                        'https://github.com/humblFINANCE/cookiecutter-python',                │ │
│ │                        │   'commit': 'd3f580ed7315f1cb472a354475c0de59de3b4730',             │ │
│ │                        │   'checkout': None,                                                 │ │
│ │                        │   'context': {                                                      │ │
│ │                        │   │   'cookiecutter': {                                             │ │
│ │                        │   │   │   'package_name': 'gitmoji-test',                           │ │
│ │                        │   │   │   'package_description': 'tests the use case of a gitmoji   │ │
│ │                        commit rule',                                                         │ │
│ │                        │   │   │   'package_url':                                            │ │
│ │                        'https://github.com/jjfantini/gitmoji-test',                          │ │
│ │                        │   │   │   'author_name': 'Jennings Fantini',                        │ │
│ │                        │   │   │   'author_email': 'jjman2811@gmail.com',                    │ │
│ │                        │   │   │   'github_username': 'jjfantini',                           │ │
│ │                        │   │   │   'python_version': '3.12.1',                               │ │
│ │                        │   │   │   'docker_image': 'python:3.12.1-slim',                     │ │
│ │                        │   │   │   'development_environment': 'strict',                      │ │
│ │                        │   │   │   'with_conventional_commits': '1',                         │ │
│ │                        │   │   │   ... +16                                                   │ │
│ │                        │   │   }                                                             │ │
│ │                        │   },                                                                │ │
│ │                        │   'directory': None                                                 │ │
│ │                        }                                                                     │ │
│ │        deleted_paths = set()                                                                 │ │
│ │           output_dir = WindowsPath('C:/Users/jjfan/AppData/Local/Temp/tmp_bidubym/current_t… │ │
│ │          project_dir = WindowsPath('.')                                                      │ │
│ │       pyproject_file = WindowsPath('pyproject.toml')                                         │ │
│ │                 repo = <git.repo.base.Repo                                                   │ │
│ │                        'C:\\Users\\jjfan\\AppData\\Local\\Temp\\tmp_bidubym\\repo\\.git'>    │ │
│ │ update_deleted_paths = True                                                                  │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                                  │
│ C:\Users\jjfan\github\gitmoji-test\menv\Lib\site-packages\cruft\_commands\utils\generate.py:111  │
│ in _get_skip_paths                                                                               │
│                                                                                                  │
│   108 def _get_skip_paths(cruft_state: CruftState, pyproject_file: Path) -> Set[Path]:           │
│   109 │   skip_cruft = cruft_state.get("skip", [])                                               │
│   110 │   if tomllib and pyproject_file.is_file():                                               │
│ ❱ 111 │   │   pyproject_cruft = tomllib.loads(pyproject_file.read_text()).get("tool", {}).get(   │
│   112 │   │   skip_cruft.extend(pyproject_cruft.get("skip", []))                                 │
│   113 │   elif pyproject_file.is_file():                                                         │
│   114 │   │   warn(                                                                              │
│                                                                                                  │
│ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │
│ │    cruft_state = {                                                                           │ │
│ │                  │   'template': 'https://github.com/humblFINANCE/cookiecutter-python',      │ │
│ │                  │   'commit': 'd3f580ed7315f1cb472a354475c0de59de3b4730',                   │ │
│ │                  │   'checkout': None,                                                       │ │
│ │                  │   'context': {                                                            │ │
│ │                  │   │   'cookiecutter': {                                                   │ │
│ │                  │   │   │   'package_name': 'gitmoji-test',                                 │ │
│ │                  │   │   │   'package_description': 'tests the use case of a gitmoji commit  │ │
│ │                  rule',                                                                      │ │
│ │                  │   │   │   'package_url': 'https://github.com/jjfantini/gitmoji-test',     │ │
│ │                  │   │   │   'author_name': 'Jennings Fantini',                              │ │
│ │                  │   │   │   'author_email': 'jjman2811@gmail.com',                          │ │
│ │                  │   │   │   'github_username': 'jjfantini',                                 │ │
│ │                  │   │   │   'python_version': '3.12.1',                                     │ │
│ │                  │   │   │   'docker_image': 'python:3.12.1-slim',                           │ │
│ │                  │   │   │   'development_environment': 'strict',                            │ │
│ │                  │   │   │   'with_conventional_commits': '1',                               │ │
│ │                  │   │   │   ... +16                                                         │ │
│ │                  │   │   }                                                                   │ │
│ │                  │   },                                                                      │ │
│ │                  │   'directory': None                                                       │ │
│ │                  }                                                                           │ │
│ │ pyproject_file = WindowsPath('pyproject.toml')                                               │ │
│ │     skip_cruft = []                                                                          │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                                  │
│ C:\Users\jjfan\github\gitmoji-test\menv\Lib\pathlib.py:1028 in read_text                         │
│                                                                                                  │
│   1025 │   │   """                                                                               │
│   1026 │   │   encoding = io.text_encoding(encoding)                                             │
│   1027 │   │   with self.open(mode='r', encoding=encoding, errors=errors) as f:                  │
│ ❱ 1028 │   │   │   return f.read()                                                               │
│   1029 │                                                                                         │
│   1030 │   def write_bytes(self, data):                                                          │
│   1031 │   │   """                                                                               │
│                                                                                                  │
│ ╭──────────────────────────────────── locals ─────────────────────────────────────╮              │
│ │ encoding = 'locale'                                                             │              │
│ │   errors = None                                                                 │              │
│ │        f = <_io.TextIOWrapper name='pyproject.toml' mode='r' encoding='cp1252'> │              │
│ │     self = WindowsPath('pyproject.toml')                                        │              │
│ ╰─────────────────────────────────────────────────────────────────────────────────╯              │
│                                                                                                  │
│ C:\Users\jjfan\github\gitmoji-test\menv\Lib\encodings\cp1252.py:23 in decode                     │
│                                                                                                  │
│    20                                                                                            │
│    21 class IncrementalDecoder(codecs.IncrementalDecoder):                                       │
│    22 │   def decode(self, input, final=False):                                                  │
│ ❱  23 │   │   return codecs.charmap_decode(input,self.errors,decoding_table)[0]                  │
│    24                                                                                            │
│    25 class StreamWriter(Codec,codecs.StreamWriter):                                             │
│    26 │   pass                                                                                   │
│                                                                                                  │
│ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │
│ │ final = True                                                                                 │ │
│ │ input = b'[build-system]  #                                                                  │ │
│ │         https://python-poetry.org/docs/pyproject/#poetry-and-pep-517\r\n'+7043               │ │
│ │  self = <encodings.cp1252.IncrementalDecoder object at 0x000001D35F940530>                   │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
UnicodeDecodeError: 'charmap' codec can't decode byte 0x90 in position 1100: character maps to <undefined>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant