Phase 2 build initial
This commit is contained in:
292
hcfs-python/build_docs.py
Normal file
292
hcfs-python/build_docs.py
Normal file
@@ -0,0 +1,292 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user