
* pyi_generator: avoid fully qualified names for reflex. types The previous method added quite a large line diff to the pyi files, so for now, lets just add the `Breakpoints` import to the default set along with Var, EventHandler, Style and others. * pyi_generator: fix generated files using ruff also generate updated pyi files in reflex/experimental namespace * remove black from dev dependencies * poetry.lock: relock deps * Update all pyi files with new formatting * pre-commit fixes * pyi_generator: fix __init__.pyi files again
121 lines
3.6 KiB
Python
121 lines
3.6 KiB
Python
"""The pyi generator module."""
|
|
|
|
import logging
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from reflex.utils.pyi_generator import PyiGenerator, _relative_to_pwd
|
|
|
|
logger = logging.getLogger("pyi_generator")
|
|
|
|
LAST_RUN_COMMIT_SHA_FILE = Path(".pyi_generator_last_run").resolve()
|
|
GENERATOR_FILE = Path(__file__).resolve()
|
|
GENERATOR_DIFF_FILE = Path(".pyi_generator_diff").resolve()
|
|
DEFAULT_TARGETS = ["reflex/components", "reflex/experimental", "reflex/__init__.py"]
|
|
|
|
|
|
def _git_diff(args: list[str]) -> str:
|
|
"""Run a git diff command.
|
|
|
|
Args:
|
|
args: The args to pass to git diff.
|
|
|
|
Returns:
|
|
The output of the git diff command.
|
|
"""
|
|
cmd = ["git", "diff", "--no-color", *args]
|
|
return subprocess.run(cmd, capture_output=True, encoding="utf-8").stdout
|
|
|
|
|
|
def _git_changed_files(args: list[str] | None = None) -> list[Path]:
|
|
"""Get the list of changed files for a git diff command.
|
|
|
|
Args:
|
|
args: The args to pass to git diff.
|
|
|
|
Returns:
|
|
The list of changed files.
|
|
"""
|
|
if not args:
|
|
args = []
|
|
|
|
if "--name-only" not in args:
|
|
args.insert(0, "--name-only")
|
|
|
|
diff = _git_diff(args).splitlines()
|
|
return [Path(file.strip()) for file in diff]
|
|
|
|
|
|
def _get_changed_files() -> list[Path] | None:
|
|
"""Get the list of changed files since the last run of the generator.
|
|
|
|
Returns:
|
|
The list of changed files, or None if all files should be regenerated.
|
|
"""
|
|
try:
|
|
last_run_commit_sha = LAST_RUN_COMMIT_SHA_FILE.read_text().strip()
|
|
except FileNotFoundError:
|
|
logger.info(
|
|
"make_pyi.py last run could not be determined, regenerating all .pyi files"
|
|
)
|
|
return None
|
|
changed_files = _git_changed_files([f"{last_run_commit_sha}..HEAD"])
|
|
# get all unstaged changes
|
|
changed_files.extend(_git_changed_files())
|
|
if _relative_to_pwd(GENERATOR_FILE) not in changed_files:
|
|
return changed_files
|
|
logger.info("make_pyi.py has changed, checking diff now")
|
|
diff = "".join(_git_diff([GENERATOR_FILE.as_posix()]).splitlines()[2:])
|
|
|
|
try:
|
|
last_diff = GENERATOR_DIFF_FILE.read_text()
|
|
if diff != last_diff:
|
|
logger.info("make_pyi.py has changed, regenerating all .pyi files")
|
|
changed_files = None
|
|
else:
|
|
logger.info("make_pyi.py has not changed, only regenerating changed files")
|
|
except FileNotFoundError:
|
|
logger.info(
|
|
"make_pyi.py diff could not be determined, regenerating all .pyi files"
|
|
)
|
|
changed_files = None
|
|
|
|
GENERATOR_DIFF_FILE.write_text(diff)
|
|
|
|
return changed_files
|
|
|
|
|
|
if __name__ == "__main__":
|
|
logging.basicConfig(level=logging.DEBUG)
|
|
logging.getLogger("blib2to3.pgen2.driver").setLevel(logging.INFO)
|
|
|
|
targets = (
|
|
[arg for arg in sys.argv[1:] if not arg.startswith("tests")]
|
|
if len(sys.argv) > 1
|
|
else DEFAULT_TARGETS
|
|
)
|
|
|
|
# Only include targets that have a prefix in the default target list
|
|
targets = [
|
|
target
|
|
for target in targets
|
|
if any(str(target).startswith(prefix) for prefix in DEFAULT_TARGETS)
|
|
]
|
|
|
|
logger.info(f"Running .pyi generator for {targets}")
|
|
|
|
changed_files = _get_changed_files()
|
|
if changed_files is None:
|
|
logger.info("Changed files could not be detected, regenerating all .pyi files")
|
|
else:
|
|
logger.info(f"Detected changed files: {changed_files}")
|
|
|
|
gen = PyiGenerator()
|
|
gen.scan_all(targets, changed_files)
|
|
|
|
current_commit_sha = subprocess.run(
|
|
["git", "rev-parse", "HEAD"], capture_output=True, encoding="utf-8"
|
|
).stdout.strip()
|
|
LAST_RUN_COMMIT_SHA_FILE.write_text(current_commit_sha)
|