mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-17 05:31:16 +08:00
138 lines
5.2 KiB
Python
138 lines
5.2 KiB
Python
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
"""Utility functions for JSON output."""
|
|
|
|
import fnmatch
|
|
from typing import Any
|
|
|
|
from sphinx.application import Sphinx
|
|
from sphinx.config import Config
|
|
from sphinx.util import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def validate_content_gating_integration(app: Sphinx) -> None:
|
|
"""Validate that content gating integration is working properly."""
|
|
# Check if content_gating extension is loaded
|
|
if "content_gating" in app.extensions:
|
|
logger.info("Content gating extension detected - JSON output will respect content gating rules")
|
|
else:
|
|
logger.debug("Content gating extension not detected - JSON output will process all documents")
|
|
|
|
# Log current exclude patterns for debugging
|
|
exclude_patterns = getattr(app.config, "exclude_patterns", [])
|
|
if exclude_patterns:
|
|
logger.debug(f"Current exclude patterns: {exclude_patterns}")
|
|
|
|
# Check current build tags for debugging
|
|
if hasattr(app, "tags"):
|
|
try:
|
|
current_tags = set(app.tags)
|
|
if current_tags:
|
|
logger.info(f"Active build tags: {current_tags}")
|
|
else:
|
|
logger.info("No build tags active")
|
|
except (TypeError, AttributeError):
|
|
logger.debug("Could not determine active build tags")
|
|
|
|
|
|
def get_setting(config: Config, key: str, default: Any = None) -> Any: # noqa: ANN401
|
|
"""Get a setting from json_output_settings with fallback to old config names."""
|
|
settings = getattr(config, "json_output_settings", {})
|
|
|
|
# Try new settings format first
|
|
if key in settings:
|
|
return settings[key]
|
|
|
|
# Fallback to old config names for backward compatibility
|
|
old_config_map = {
|
|
"enabled": "json_output_enabled",
|
|
"exclude_patterns": "json_output_exclude_patterns",
|
|
"verbose": "json_output_verbose",
|
|
"parallel": "json_output_parallel",
|
|
"include_children": "json_output_include_children",
|
|
"include_child_content": "json_output_include_child_content",
|
|
"main_index_mode": "json_output_main_index_mode",
|
|
"max_main_index_docs": "json_output_max_main_index_docs",
|
|
}
|
|
|
|
old_key = old_config_map.get(key)
|
|
if old_key and hasattr(config, old_key):
|
|
return getattr(config, old_key)
|
|
|
|
return default
|
|
|
|
|
|
def is_content_gated(config: Config, docname: str) -> bool:
|
|
"""
|
|
Check if a document is content gated by checking Sphinx's exclude_patterns.
|
|
This works with the content_gating extension that adds restricted documents
|
|
to exclude_patterns during config-inited event.
|
|
"""
|
|
sphinx_exclude_patterns = getattr(config, "exclude_patterns", [])
|
|
if not sphinx_exclude_patterns:
|
|
return False
|
|
|
|
# Convert docname to potential file paths that might be in exclude_patterns
|
|
possible_paths = [docname + ".md", docname + ".rst", docname]
|
|
|
|
for possible_path in possible_paths:
|
|
# Check if this path matches any exclude pattern using fnmatch (supports glob patterns)
|
|
for pattern in sphinx_exclude_patterns:
|
|
if isinstance(pattern, str) and fnmatch.fnmatch(possible_path, pattern):
|
|
logger.debug(f"Document {docname} is content gated (matches pattern: {pattern})")
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
def should_generate_json(config: Config, docname: str) -> bool:
|
|
"""Check if JSON should be generated for this document."""
|
|
if not get_setting(config, "enabled", True):
|
|
return False
|
|
|
|
if not docname or not isinstance(docname, str):
|
|
logger.warning(f"Invalid docname for JSON generation: {docname}")
|
|
return False
|
|
|
|
# CRITICAL: Check content gating first - if document is content gated, don't generate JSON
|
|
if is_content_gated(config, docname):
|
|
logger.info(f"Excluding {docname} from JSON generation due to content gating")
|
|
return False
|
|
|
|
# Check JSON output extension's own exclude patterns
|
|
for pattern in get_setting(config, "exclude_patterns", []):
|
|
if isinstance(pattern, str) and docname.startswith(pattern):
|
|
return False
|
|
|
|
return True
|
|
|
|
|
|
def get_document_url(app: Sphinx, docname: str) -> str:
|
|
"""Get the URL for a document."""
|
|
if not docname or not isinstance(docname, str):
|
|
logger.warning(f"Invalid docname for URL generation: {docname}")
|
|
return "invalid.html"
|
|
|
|
try:
|
|
if hasattr(app.builder, "get_target_uri"):
|
|
return app.builder.get_target_uri(docname)
|
|
except Exception as e: # noqa: BLE001
|
|
logger.warning(f"Failed to get target URI for {docname}: {e}")
|
|
|
|
return docname + ".html"
|