Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f483cf978c | ||
|
|
0e12e3a531 | ||
|
|
67bea9a2a7 | ||
|
|
a05c8236f6 |
@@ -276,6 +276,6 @@ def _devmode_respond(request: Request, name=""):
|
|||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
status_code=409,
|
status_code=409,
|
||||||
content={
|
content={
|
||||||
"detail": "Frontend assets served by Vite in debug mode. You are on backend, connect to frontend instead."
|
"detail": "[devmode] Not serving frontend files here. Should you connect to Vite instead?"
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
+58
-28
@@ -26,9 +26,6 @@ import tomlkit
|
|||||||
|
|
||||||
version = importlib.metadata.version("fastapi-vue-setup")
|
version = importlib.metadata.version("fastapi-vue-setup")
|
||||||
|
|
||||||
# Track Python files written/patched for ruff formatting
|
|
||||||
_python_files_to_format: list[Path] = []
|
|
||||||
|
|
||||||
# Template directory
|
# Template directory
|
||||||
TEMPLATE_DIR = Path(__file__).parent / "template"
|
TEMPLATE_DIR = Path(__file__).parent / "template"
|
||||||
|
|
||||||
@@ -41,21 +38,49 @@ def print_boxed(text: str) -> None:
|
|||||||
print(f"╰{'─' * width}╯")
|
print(f"╰{'─' * width}╯")
|
||||||
|
|
||||||
|
|
||||||
def ruff_sort_imports(files: list[Path], dry: bool = False) -> None:
|
def ruff_format_content(content: str, target_path: Path) -> str:
|
||||||
"""Run ruff to sort imports in the given Python files."""
|
"""Format Python content using ruff with project settings.
|
||||||
if not files:
|
|
||||||
return
|
Writes to a temp file (.new.py) next to target, runs ruff check (import sorting)
|
||||||
py_files = [str(f) for f in files if f.suffix == ".py" and f.exists()]
|
and ruff format on it, reads back the result, and cleans up.
|
||||||
if not py_files:
|
Returns the formatted content, or original if ruff fails.
|
||||||
return
|
"""
|
||||||
if dry:
|
temp_file = target_path.with_suffix(".new.py")
|
||||||
print(f"🔧 Would run ruff import sorting on {len(py_files)} files")
|
try:
|
||||||
return
|
temp_file.write_text(content, "UTF-8", newline="\n")
|
||||||
print("🔧 Ruff isort on modified files")
|
# Sort imports first
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
[sys.executable, "-m", "ruff", "check", "--select", "I", "--fix", *py_files],
|
[
|
||||||
stdout=subprocess.DEVNULL,
|
"uv",
|
||||||
)
|
"run",
|
||||||
|
"--with",
|
||||||
|
"ruff",
|
||||||
|
"ruff",
|
||||||
|
"check",
|
||||||
|
"--select",
|
||||||
|
"I",
|
||||||
|
"--fix",
|
||||||
|
str(temp_file),
|
||||||
|
],
|
||||||
|
cwd=target_path.parent,
|
||||||
|
capture_output=True,
|
||||||
|
)
|
||||||
|
# Then format
|
||||||
|
result = subprocess.run(
|
||||||
|
["uv", "run", "--with", "ruff", "ruff", "format", str(temp_file)],
|
||||||
|
cwd=target_path.parent,
|
||||||
|
capture_output=True,
|
||||||
|
)
|
||||||
|
if result.returncode == 0:
|
||||||
|
return temp_file.read_text("UTF-8")
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
try:
|
||||||
|
temp_file.unlink(missing_ok=True)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return content
|
||||||
|
|
||||||
|
|
||||||
def uv_add_packages(
|
def uv_add_packages(
|
||||||
@@ -655,7 +680,6 @@ def patch_app_file(
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
path.write_text(content, "UTF-8", newline="\n")
|
path.write_text(content, "UTF-8", newline="\n")
|
||||||
_python_files_to_format.append(path)
|
|
||||||
print(f"✅ Patched {path}")
|
print(f"✅ Patched {path}")
|
||||||
|
|
||||||
if not lifespan_patched:
|
if not lifespan_patched:
|
||||||
@@ -903,13 +927,20 @@ def write_file(
|
|||||||
the content will be written to fallback_path instead of being skipped.
|
the content will be written to fallback_path instead of being skipped.
|
||||||
|
|
||||||
If force=True, always overwrite without checking for upgrade marker.
|
If force=True, always overwrite without checking for upgrade marker.
|
||||||
|
|
||||||
|
Python files (.py) are automatically formatted using ruff with the project's
|
||||||
|
settings before writing.
|
||||||
"""
|
"""
|
||||||
|
# Format Python content using project settings before any comparison/writing
|
||||||
|
if path.suffix == ".py":
|
||||||
|
content = ruff_format_content(content, path)
|
||||||
|
|
||||||
exists = path.exists()
|
exists = path.exists()
|
||||||
if exists and not overwrite:
|
if exists and not overwrite:
|
||||||
print(f"⚠️ Skipping {path} (exists)")
|
print(f"⚠️ Skipping {path} (exists)")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Check if content is the same
|
# Check if content is the same (new content already formatted)
|
||||||
if exists:
|
if exists:
|
||||||
existing_content = path.read_text("UTF-8")
|
existing_content = path.read_text("UTF-8")
|
||||||
if existing_content == content:
|
if existing_content == content:
|
||||||
@@ -935,8 +966,6 @@ def write_file(
|
|||||||
path.write_text(content, "UTF-8", newline="\n")
|
path.write_text(content, "UTF-8", newline="\n")
|
||||||
if executable and sys.platform != "win32":
|
if executable and sys.platform != "win32":
|
||||||
path.chmod(path.stat().st_mode | 0o111)
|
path.chmod(path.stat().st_mode | 0o111)
|
||||||
if path.suffix == ".py":
|
|
||||||
_python_files_to_format.append(path)
|
|
||||||
action = "Updated" if exists else "Created"
|
action = "Updated" if exists else "Created"
|
||||||
print(f"✅ {action} {path}")
|
print(f"✅ {action} {path}")
|
||||||
return True
|
return True
|
||||||
@@ -949,10 +978,14 @@ def _write_fallback_file(
|
|||||||
dry: bool,
|
dry: bool,
|
||||||
executable: bool,
|
executable: bool,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""Write content to a fallback .new.py file when original can't be overwritten."""
|
"""Write content to a fallback .new.py file when original can't be overwritten.
|
||||||
# Check if fallback already has same content
|
|
||||||
|
Note: content should already be formatted before calling this function.
|
||||||
|
"""
|
||||||
|
# Check if fallback already has same content (content already formatted)
|
||||||
if fallback_path.exists():
|
if fallback_path.exists():
|
||||||
if fallback_path.read_text("UTF-8") == content:
|
existing_content = fallback_path.read_text("UTF-8")
|
||||||
|
if existing_content == content:
|
||||||
print(f"✔️ {fallback_path} (already up to date)")
|
print(f"✔️ {fallback_path} (already up to date)")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -965,8 +998,6 @@ def _write_fallback_file(
|
|||||||
fallback_path.write_text(content, "UTF-8", newline="\n")
|
fallback_path.write_text(content, "UTF-8", newline="\n")
|
||||||
if executable and sys.platform != "win32":
|
if executable and sys.platform != "win32":
|
||||||
fallback_path.chmod(fallback_path.stat().st_mode | 0o111)
|
fallback_path.chmod(fallback_path.stat().st_mode | 0o111)
|
||||||
if fallback_path.suffix == ".py":
|
|
||||||
_python_files_to_format.append(fallback_path)
|
|
||||||
print(f"✅ Created {fallback_path} (original customized by user)")
|
print(f"✅ Created {fallback_path} (original customized by user)")
|
||||||
_new_files_written.append((fallback_path, original_path))
|
_new_files_written.append((fallback_path, original_path))
|
||||||
return True
|
return True
|
||||||
@@ -1440,7 +1471,6 @@ def cmd_setup(args: argparse.Namespace) -> int:
|
|||||||
print("✅ Created .gitignore")
|
print("✅ Created .gitignore")
|
||||||
|
|
||||||
# === Add dependencies using uv ===
|
# === Add dependencies using uv ===
|
||||||
ruff_sort_imports(_python_files_to_format, dry=dry)
|
|
||||||
if dry:
|
if dry:
|
||||||
print("📦 Would add: fastapi[standard], fastapi-vue, httpx (dev only)")
|
print("📦 Would add: fastapi[standard], fastapi-vue, httpx (dev only)")
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import os
|
|||||||
from fastapi_vue import server
|
from fastapi_vue import server
|
||||||
|
|
||||||
DEFAULT_PORT = TEMPLATE_DEFAULT_PORT
|
DEFAULT_PORT = TEMPLATE_DEFAULT_PORT
|
||||||
DEVMODE = bool(os.getenv("ENVPREFIX_DEV") == "1")
|
DEVMODE = os.getenv("ENVPREFIX_DEV") == "1"
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|||||||
@@ -56,7 +56,8 @@ def main():
|
|||||||
epilog=HELP_EPILOG,
|
epilog=HELP_EPILOG,
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-l", "--listen",
|
"-l",
|
||||||
|
"--listen",
|
||||||
metavar="host:port",
|
metavar="host:port",
|
||||||
help=f"Vite (default: localhost:{DEFAULT_VITE_PORT})",
|
help=f"Vite (default: localhost:{DEFAULT_VITE_PORT})",
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user