mirror of
https://github.com/apache/superset.git
synced 2026-04-17 07:05:04 +00:00
chore(extensions): clean up backend entrypoints and file globs (#38360)
This commit is contained in:
@@ -162,8 +162,13 @@ def build_manifest(cwd: Path, remote_entry: str | None) -> Manifest:
|
||||
)
|
||||
|
||||
backend: ManifestBackend | None = None
|
||||
if extension.backend and extension.backend.entryPoints:
|
||||
backend = ManifestBackend(entryPoints=extension.backend.entryPoints)
|
||||
backend_dir = cwd / "backend"
|
||||
if backend_dir.exists():
|
||||
# Generate conventional entry point
|
||||
publisher_snake = kebab_to_snake_case(extension.publisher)
|
||||
name_snake = kebab_to_snake_case(extension.name)
|
||||
entrypoint = f"superset_extensions.{publisher_snake}.{name_snake}.entrypoint"
|
||||
backend = ManifestBackend(entrypoint=entrypoint)
|
||||
|
||||
return Manifest(
|
||||
id=composite_id,
|
||||
@@ -217,17 +222,34 @@ def copy_frontend_dist(cwd: Path) -> str:
|
||||
|
||||
|
||||
def copy_backend_files(cwd: Path) -> None:
|
||||
"""Copy backend files based on pyproject.toml build configuration (validation already passed)."""
|
||||
dist_dir = cwd / "dist"
|
||||
extension = read_json(cwd / "extension.json")
|
||||
if not extension:
|
||||
click.secho("❌ No extension.json file found.", err=True, fg="red")
|
||||
sys.exit(1)
|
||||
backend_dir = cwd / "backend"
|
||||
|
||||
for pat in extension.get("backend", {}).get("files", []):
|
||||
for f in cwd.glob(pat):
|
||||
# Read build config from pyproject.toml
|
||||
pyproject = read_toml(backend_dir / "pyproject.toml")
|
||||
assert pyproject
|
||||
build_config = (
|
||||
pyproject.get("tool", {}).get("apache_superset_extensions", {}).get("build", {})
|
||||
)
|
||||
include_patterns = build_config.get("include", [])
|
||||
exclude_patterns = build_config.get("exclude", [])
|
||||
|
||||
# Process include patterns
|
||||
for pattern in include_patterns:
|
||||
for f in backend_dir.glob(pattern):
|
||||
if not f.is_file():
|
||||
continue
|
||||
tgt = dist_dir / f.relative_to(cwd)
|
||||
|
||||
# Check exclude patterns
|
||||
relative_path = f.relative_to(backend_dir)
|
||||
should_exclude = any(
|
||||
relative_path.match(excl_pattern) for excl_pattern in exclude_patterns
|
||||
)
|
||||
if should_exclude:
|
||||
continue
|
||||
|
||||
tgt = dist_dir / "backend" / relative_path
|
||||
tgt.parent.mkdir(parents=True, exist_ok=True)
|
||||
shutil.copy2(f, tgt)
|
||||
|
||||
@@ -272,6 +294,89 @@ def app() -> None:
|
||||
def validate() -> None:
|
||||
validate_npm()
|
||||
|
||||
cwd = Path.cwd()
|
||||
|
||||
# Validate extension.json exists and is valid
|
||||
extension_data = read_json(cwd / "extension.json")
|
||||
if not extension_data:
|
||||
click.secho("❌ extension.json not found.", err=True, fg="red")
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
extension = ExtensionConfig.model_validate(extension_data)
|
||||
except Exception as e:
|
||||
click.secho(f"❌ Invalid extension.json: {e}", err=True, fg="red")
|
||||
sys.exit(1)
|
||||
|
||||
# Validate conventional backend structure if backend directory exists
|
||||
backend_dir = cwd / "backend"
|
||||
if backend_dir.exists():
|
||||
# Check for pyproject.toml
|
||||
pyproject_path = backend_dir / "pyproject.toml"
|
||||
if not pyproject_path.exists():
|
||||
click.secho(
|
||||
"❌ Backend directory exists but pyproject.toml not found",
|
||||
err=True,
|
||||
fg="red",
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
# Validate pyproject.toml has build configuration
|
||||
pyproject = read_toml(pyproject_path)
|
||||
if not pyproject:
|
||||
click.secho("❌ Failed to read backend pyproject.toml", err=True, fg="red")
|
||||
sys.exit(1)
|
||||
|
||||
build_config = (
|
||||
pyproject.get("tool", {})
|
||||
.get("apache_superset_extensions", {})
|
||||
.get("build", {})
|
||||
)
|
||||
if not build_config.get("include"):
|
||||
click.secho(
|
||||
"❌ Missing [tool.apache_superset_extensions.build] section with 'include' patterns in pyproject.toml",
|
||||
err=True,
|
||||
fg="red",
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
# Check conventional backend entry point
|
||||
publisher_snake = kebab_to_snake_case(extension.publisher)
|
||||
name_snake = kebab_to_snake_case(extension.name)
|
||||
expected_entry_file = (
|
||||
backend_dir
|
||||
/ "src"
|
||||
/ "superset_extensions"
|
||||
/ publisher_snake
|
||||
/ name_snake
|
||||
/ "entrypoint.py"
|
||||
)
|
||||
|
||||
if not expected_entry_file.exists():
|
||||
click.secho(
|
||||
f"❌ Backend entry point not found at expected location: {expected_entry_file.relative_to(cwd)}",
|
||||
err=True,
|
||||
fg="red",
|
||||
)
|
||||
click.secho(
|
||||
f" Convention requires: backend/src/superset_extensions/{publisher_snake}/{name_snake}/entrypoint.py",
|
||||
fg="yellow",
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
# Validate conventional frontend entry point if frontend directory exists
|
||||
frontend_dir = cwd / "frontend"
|
||||
if frontend_dir.exists():
|
||||
expected_frontend_entry = frontend_dir / "src" / "index.tsx"
|
||||
if not expected_frontend_entry.exists():
|
||||
click.secho(
|
||||
f"❌ Frontend entry point not found at expected location: {expected_frontend_entry.relative_to(cwd)}",
|
||||
err=True,
|
||||
fg="red",
|
||||
)
|
||||
click.secho(" Convention requires: frontend/src/index.tsx", fg="yellow")
|
||||
sys.exit(1)
|
||||
|
||||
click.secho("✅ Validation successful", fg="green")
|
||||
|
||||
|
||||
|
||||
@@ -2,3 +2,10 @@
|
||||
name = "{{ backend_package }}"
|
||||
version = "{{ version }}"
|
||||
license = "{{ license }}"
|
||||
|
||||
[tool.apache_superset_extensions.build]
|
||||
# Files to include in the extension build/bundle
|
||||
include = [
|
||||
"src/{{ backend_path|replace('.', '/') }}/**/*.py",
|
||||
]
|
||||
exclude = []
|
||||
|
||||
@@ -4,11 +4,5 @@
|
||||
"displayName": "{{ display_name }}",
|
||||
"version": "{{ version }}",
|
||||
"license": "{{ license }}",
|
||||
{% if include_backend -%}
|
||||
"backend": {
|
||||
"entryPoints": ["{{ backend_entry }}"],
|
||||
"files": ["backend/src/{{ backend_path|replace('.', '/') }}/**/*.py"]
|
||||
},
|
||||
{% endif -%}
|
||||
"permissions": []
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user