mirror of
https://github.com/django-components/django-components.git
synced 2025-09-26 15:39:08 +00:00
refactor: fix clash with autodiscovery
This commit is contained in:
parent
ddc62c7dfc
commit
003c8ba4d5
3 changed files with 31 additions and 19 deletions
|
@ -1,8 +1,7 @@
|
||||||
import importlib
|
import importlib
|
||||||
import importlib.util
|
import importlib.util
|
||||||
import sys
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Union
|
|
||||||
|
|
||||||
import django
|
import django
|
||||||
from django.utils.module_loading import autodiscover_modules
|
from django.utils.module_loading import autodiscover_modules
|
||||||
|
@ -21,7 +20,7 @@ def autodiscover() -> None:
|
||||||
autodiscover_modules("components")
|
autodiscover_modules("components")
|
||||||
|
|
||||||
# Autodetect a <component>.py file in a components dir
|
# Autodetect a <component>.py file in a components dir
|
||||||
component_filepaths = search(search_glob="**/*.py")
|
component_filepaths = search(search_glob="**/*.py").matched_files
|
||||||
for path in component_filepaths:
|
for path in component_filepaths:
|
||||||
import_file(path)
|
import_file(path)
|
||||||
|
|
||||||
|
@ -29,12 +28,20 @@ def autodiscover() -> None:
|
||||||
importlib.import_module(path_lib)
|
importlib.import_module(path_lib)
|
||||||
|
|
||||||
|
|
||||||
def import_file(path: Union[str, Path]) -> None:
|
def import_file(file_path: Path) -> None:
|
||||||
MODULE_PATH = path
|
# Get the root dir, see https://stackoverflow.com/a/16413955/9788634
|
||||||
MODULE_NAME = Path(path).stem
|
project_root = os.path.abspath(os.path.dirname(__name__))
|
||||||
spec = importlib.util.spec_from_file_location(MODULE_NAME, MODULE_PATH)
|
|
||||||
if spec is None:
|
# Derive python import path from the filesystem path
|
||||||
raise ValueError(f"Cannot import file '{path}' - invalid path")
|
# Example:
|
||||||
module = importlib.util.module_from_spec(spec)
|
# If project root is `/path/to/project`
|
||||||
sys.modules[spec.name] = module
|
# And file_path is `/path/to/project/app/components/mycomp.py`
|
||||||
spec.loader.exec_module(module) # type: ignore
|
# 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=project_root)
|
||||||
|
rel_path_without_suffix = str(Path(rel_path).with_suffix(""))
|
||||||
|
module_name = rel_path_without_suffix.replace(os.sep, ".")
|
||||||
|
|
||||||
|
# This imports the file and runs it's code. So if the file defines any
|
||||||
|
# django components, they will be registered.
|
||||||
|
importlib.import_module(module_name)
|
||||||
|
|
|
@ -89,7 +89,7 @@ def _resolve_component_relative_files(attrs: MutableMapping) -> None:
|
||||||
|
|
||||||
# Prepare all possible directories we need to check when searching for
|
# Prepare all possible directories we need to check when searching for
|
||||||
# component's template and media files
|
# component's template and media files
|
||||||
components_dirs = search()
|
components_dirs = search().searched_dirs
|
||||||
|
|
||||||
# Get the directory where the component class is defined
|
# Get the directory where the component class is defined
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -1,13 +1,18 @@
|
||||||
import glob
|
import glob
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List, Optional, Union
|
from typing import List, Optional, NamedTuple
|
||||||
|
|
||||||
from django.template.engine import Engine
|
from django.template.engine import Engine
|
||||||
|
|
||||||
from django_components.template_loader import Loader
|
from django_components.template_loader import Loader
|
||||||
|
|
||||||
|
|
||||||
def search(search_glob: Optional[str] = None, engine: Optional[Engine] = None) -> Union[List[str], List[Path]]:
|
class SearchResult(NamedTuple):
|
||||||
|
searched_dirs: List[Path]
|
||||||
|
matched_files: List[Path]
|
||||||
|
|
||||||
|
|
||||||
|
def search(search_glob: Optional[str] = None, engine: Optional[Engine] = None) -> SearchResult:
|
||||||
"""
|
"""
|
||||||
Search for directories that may contain components.
|
Search for directories that may contain components.
|
||||||
|
|
||||||
|
@ -22,11 +27,11 @@ def search(search_glob: Optional[str] = None, engine: Optional[Engine] = None) -
|
||||||
dirs = loader.get_dirs()
|
dirs = loader.get_dirs()
|
||||||
|
|
||||||
if search_glob is None:
|
if search_glob is None:
|
||||||
return dirs
|
return SearchResult(searched_dirs=dirs, matched_files=[])
|
||||||
|
|
||||||
component_filenames: List[str] = []
|
component_filenames: List[Path] = []
|
||||||
for directory in dirs:
|
for directory in dirs:
|
||||||
for path in glob.iglob(str(Path(directory) / search_glob), recursive=True):
|
for path in glob.iglob(str(Path(directory) / search_glob), recursive=True):
|
||||||
component_filenames.append(path)
|
component_filenames.append(Path(path))
|
||||||
|
|
||||||
return component_filenames
|
return SearchResult(searched_dirs=dirs, matched_files=component_filenames)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue