#!/usr/bin/env python3 """ HCFS Documentation Builder Builds comprehensive documentation including: - HTML documentation with Sphinx - PDF documentation with rst2pdf and LaTeX - OpenAPI/Swagger documentation - SDK API documentation """ import os import sys import subprocess import shutil from pathlib import Path import argparse def run_command(cmd, cwd=None, check=True): """Run a shell command and return the result.""" print(f"Running: {cmd}") result = subprocess.run(cmd, shell=True, cwd=cwd, check=check, capture_output=True, text=True) if result.stdout: print(result.stdout) if result.stderr: print(result.stderr, file=sys.stderr) return result def setup_environment(): """Set up the documentation build environment.""" print("Setting up documentation environment...") # Change to docs directory docs_dir = Path(__file__).parent / "docs" os.chdir(docs_dir) # Install documentation dependencies run_command("pip install -r requirements.txt") # Create necessary directories (docs_dir / "_static").mkdir(exist_ok=True) (docs_dir / "_templates").mkdir(exist_ok=True) (docs_dir / "api" / "generated").mkdir(parents=True, exist_ok=True) return docs_dir def generate_api_docs(docs_dir): """Generate API documentation from Python source.""" print("Generating API documentation...") # Generate API docs with sphinx-apidoc hcfs_source = docs_dir.parent / "hcfs" api_output = docs_dir / "api" run_command(f"sphinx-apidoc -o {api_output} {hcfs_source} --force --separate") print("API documentation generated successfully!") def build_html_docs(docs_dir): """Build HTML documentation.""" print("Building HTML documentation...") html_output = docs_dir / "_build" / "html" # Clean previous build if html_output.exists(): shutil.rmtree(html_output) # Build HTML docs run_command("make html") print(f"HTML documentation built successfully in {html_output}") return html_output def build_pdf_docs(docs_dir): """Build PDF documentation using multiple methods.""" print("Building PDF documentation...") pdf_output = docs_dir / "_build" / "pdf" pdf_output.mkdir(parents=True, exist_ok=True) # Method 1: Using rst2pdf (faster, simpler) try: print("Building PDF with rst2pdf...") run_command("make pdf") # Find and copy PDF file pdf_files = list((docs_dir / "_build" / "pdf").glob("*.pdf")) if pdf_files: main_pdf = pdf_files[0] final_pdf = pdf_output / "HCFS-Documentation.pdf" shutil.copy2(main_pdf, final_pdf) print(f"rst2pdf documentation: {final_pdf}") except subprocess.CalledProcessError: print("rst2pdf failed, trying LaTeX method...") # Method 2: Using LaTeX (higher quality, slower) try: print("Building PDF with LaTeX...") run_command("make latexpdf") # Find and copy LaTeX PDF latex_pdf = docs_dir / "_build" / "latex" / "HCFS.pdf" if latex_pdf.exists(): final_latex_pdf = pdf_output / "HCFS-Documentation-LaTeX.pdf" shutil.copy2(latex_pdf, final_latex_pdf) print(f"LaTeX PDF documentation: {final_latex_pdf}") except subprocess.CalledProcessError: print("LaTeX PDF generation failed (this is normal if LaTeX is not installed)") return pdf_output def build_epub_docs(docs_dir): """Build EPUB documentation.""" print("Building EPUB documentation...") try: run_command("make epub") epub_file = docs_dir / "_build" / "epub" / "HCFS.epub" if epub_file.exists(): print(f"EPUB documentation: {epub_file}") return epub_file except subprocess.CalledProcessError: print("EPUB generation failed") return None def validate_openapi_spec(): """Validate the OpenAPI specification.""" print("Validating OpenAPI specification...") openapi_file = Path(__file__).parent / "openapi.yaml" if not openapi_file.exists(): print("Warning: OpenAPI specification not found") return False try: # Try to validate with swagger-codegen if available run_command(f"swagger-codegen validate -i {openapi_file}", check=False) except FileNotFoundError: print("swagger-codegen not found, skipping OpenAPI validation") return True def generate_coverage_report(docs_dir): """Generate documentation coverage report.""" print("Generating documentation coverage report...") try: run_command("make coverage") coverage_file = docs_dir / "_build" / "coverage" / "python.txt" if coverage_file.exists(): print(f"Documentation coverage report: {coverage_file}") # Print summary with open(coverage_file, 'r') as f: content = f.read() print("Documentation Coverage Summary:") print("=" * 40) print(content[-500:]) # Print last 500 characters except subprocess.CalledProcessError: print("Coverage report generation failed") def create_deployment_package(docs_dir, html_output, pdf_output): """Create a deployment package with all documentation.""" print("Creating deployment package...") deploy_dir = docs_dir.parent / "docs-deploy" if deploy_dir.exists(): shutil.rmtree(deploy_dir) deploy_dir.mkdir() # Copy HTML documentation html_deploy = deploy_dir / "html" shutil.copytree(html_output, html_deploy) # Copy PDF files pdf_deploy = deploy_dir / "pdf" pdf_deploy.mkdir() for pdf_file in pdf_output.glob("*.pdf"): shutil.copy2(pdf_file, pdf_deploy) # Copy OpenAPI spec openapi_file = docs_dir.parent / "openapi.yaml" if openapi_file.exists(): shutil.copy2(openapi_file, deploy_dir / "openapi.yaml") # Create index file index_content = """