fix: set paths for component media as posix paths even on windows (#799)

* fix: set paths for component media as posix paths even on windows

* refactor: try running django server in windows

* refactor: handle Windows paths in component media

* refactor: temp test only windows

* refactor: try to fix tests

* refactor: more test fixes

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* refactor: remove extraneous import

* refactor: more fixes

* refactor: fix path conversion for windows

* refactor: revert windows env in CI

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Juro Oravec 2024-12-02 19:03:41 +01:00 committed by GitHub
parent 230ceee537
commit 025562ac0c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 110 additions and 82 deletions

View file

@ -226,7 +226,8 @@ def _normalize_media_filepath(filepath: Any) -> Union[str, SafeData]:
return filepath
if isinstance(filepath, (Path, os.PathLike)) or hasattr(filepath, "__fspath__"):
filepath = filepath.__fspath__()
# In case of Windows OS, convert to forward slashes
filepath = Path(filepath.__fspath__()).as_posix()
if isinstance(filepath, bytes):
filepath = filepath.decode("utf-8")
@ -293,19 +294,21 @@ def _resolve_component_relative_files(attrs: MutableMapping) -> None:
# If not, don't modify anything.
def resolve_file(filepath: Union[str, SafeData]) -> Union[str, SafeData]:
if isinstance(filepath, str):
maybe_resolved_filepath = os.path.join(comp_dir_abs, filepath)
component_import_filepath = os.path.join(comp_dir_rel, filepath)
filepath_abs = os.path.join(comp_dir_abs, filepath)
# NOTE: The paths to resources need to use POSIX (forward slashes) for Django to wor
# See https://github.com/EmilStenstrom/django-components/issues/796
filepath_rel_to_comp_dir = Path(os.path.join(comp_dir_rel, filepath)).as_posix()
if os.path.isfile(maybe_resolved_filepath):
if os.path.isfile(filepath_abs):
# NOTE: It's important to use `repr`, so we don't trigger __str__ on SafeStrings
logger.debug(
f"Interpreting template '{repr(filepath)}' of component '{module_name}'"
" relatively to component file"
)
return component_import_filepath
return filepath
return filepath_rel_to_comp_dir
# If resolved absolute path does NOT exist or filepath is NOT a string, then return as is
logger.debug(
f"Interpreting template '{repr(filepath)}' of component '{module_name}'"
" relatively to components directory"

View file

@ -1,6 +1,6 @@
import glob
import os
from pathlib import Path
from pathlib import Path, PurePosixPath, PureWindowsPath
from typing import List, NamedTuple, Optional, Set, Union
from django.apps import apps
@ -211,13 +211,11 @@ def _filepath_to_python_module(
- Then the path relative to project root is `app/components/mycomp.py`
- Which we then turn into python import path `app.components.mycomp`
"""
rel_path = os.path.relpath(file_path, start=root_fs_path)
rel_path_without_suffix = str(Path(rel_path).with_suffix(""))
path_cls = PureWindowsPath if os.name == "nt" else PurePosixPath
# NOTE: `Path` normalizes paths to use `/` as separator, while `os.path`
# uses `os.path.sep`.
sep = os.path.sep if os.path.sep in rel_path_without_suffix else "/"
module_name = rel_path_without_suffix.replace(sep, ".")
rel_path = path_cls(file_path).relative_to(path_cls(root_fs_path))
rel_path_parts = rel_path.with_suffix("").parts
module_name = ".".join(rel_path_parts)
# Combine with the base module path
full_module_name = f"{root_module_path}.{module_name}" if root_module_path else module_name