292 lines
9.1 KiB
Python
292 lines
9.1 KiB
Python
#!/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 = """<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>HCFS Documentation</title>
|
|
<style>
|
|
body { font-family: Arial, sans-serif; margin: 40px; }
|
|
.section { margin: 20px 0; }
|
|
.link { display: block; margin: 5px 0; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>HCFS Documentation</h1>
|
|
|
|
<div class="section">
|
|
<h2>HTML Documentation</h2>
|
|
<a href="html/index.html" class="link">Browse HTML Documentation</a>
|
|
</div>
|
|
|
|
<div class="section">
|
|
<h2>PDF Documentation</h2>
|
|
<a href="pdf/HCFS-Documentation.pdf" class="link">Download PDF (rst2pdf)</a>
|
|
<a href="pdf/HCFS-Documentation-LaTeX.pdf" class="link">Download PDF (LaTeX)</a>
|
|
</div>
|
|
|
|
<div class="section">
|
|
<h2>API Reference</h2>
|
|
<a href="openapi.yaml" class="link">OpenAPI Specification (YAML)</a>
|
|
<a href="html/api/reference.html" class="link">API Reference (HTML)</a>
|
|
</div>
|
|
</body>
|
|
</html>"""
|
|
|
|
with open(deploy_dir / "index.html", 'w') as f:
|
|
f.write(index_content)
|
|
|
|
print(f"Deployment package created: {deploy_dir}")
|
|
return deploy_dir
|
|
|
|
def main():
|
|
"""Main documentation build process."""
|
|
parser = argparse.ArgumentParser(description="Build HCFS documentation")
|
|
parser.add_argument("--format", choices=["html", "pdf", "epub", "all"],
|
|
default="all", help="Documentation format to build")
|
|
parser.add_argument("--skip-api", action="store_true",
|
|
help="Skip API documentation generation")
|
|
parser.add_argument("--skip-validation", action="store_true",
|
|
help="Skip OpenAPI validation")
|
|
parser.add_argument("--deploy", action="store_true",
|
|
help="Create deployment package")
|
|
|
|
args = parser.parse_args()
|
|
|
|
print("HCFS Documentation Builder")
|
|
print("=" * 50)
|
|
|
|
# Setup environment
|
|
docs_dir = setup_environment()
|
|
|
|
# Generate API documentation
|
|
if not args.skip_api:
|
|
generate_api_docs(docs_dir)
|
|
|
|
# Validate OpenAPI spec
|
|
if not args.skip_validation:
|
|
validate_openapi_spec()
|
|
|
|
# Build documentation formats
|
|
html_output = None
|
|
pdf_output = None
|
|
epub_output = None
|
|
|
|
if args.format in ["html", "all"]:
|
|
html_output = build_html_docs(docs_dir)
|
|
|
|
if args.format in ["pdf", "all"]:
|
|
pdf_output = build_pdf_docs(docs_dir)
|
|
|
|
if args.format in ["epub", "all"]:
|
|
epub_output = build_epub_docs(docs_dir)
|
|
|
|
# Generate coverage report
|
|
generate_coverage_report(docs_dir)
|
|
|
|
# Create deployment package
|
|
if args.deploy and html_output:
|
|
create_deployment_package(docs_dir, html_output, pdf_output or docs_dir / "_build" / "pdf")
|
|
|
|
print("\nDocumentation build completed successfully!")
|
|
print("=" * 50)
|
|
|
|
if html_output:
|
|
print(f"HTML documentation: {html_output}/index.html")
|
|
if pdf_output:
|
|
print(f"PDF documentation: {pdf_output}")
|
|
if epub_output:
|
|
print(f"EPUB documentation: {epub_output}")
|
|
|
|
if __name__ == "__main__":
|
|
main() |