# VB6Parse Documentation Scripts
This directory contains scripts for generating documentation, test coverage, and performance benchmark data for the VB6Parse documentation site.
**Note:** The `Getting Started` guide (`docs/getting-started.html`) now loads code examples dynamically from GitHub CDN. Examples in `examples/docs/` are loaded at page load time, ensuring documentation always shows current, working code.
## Scripts
### `generate-library-docs.py`
Pure Python3 script that generates VB6 Library Reference documentation from Rust source files. Works on both Windows and Linux.
### `generate-coverage.py`
Pure Python3 script that generates test coverage data and test statistics. Works on both Windows and Linux.
### `generate-benchmarks.py`
Pure Python3 script that generates performance benchmark data from Criterion results. Works on both Windows and Linux.
### Legacy Scripts
The original Bash scripts (`generate-coverage.sh` and `generate-benchmarks.sh`) are deprecated in favor of the Python3 versions for cross-platform compatibility.
---
## Library Documentation Generation (`generate-library-docs.py`)
### Usage
```bash
# Generate documentation (default paths)
./scripts/generate-library-docs.py
# With custom paths
python3 scripts/generate-library-docs.py \
--src src/syntax/library \
--output docs/library
# Clean output directory before generating
python3 scripts/generate-library-docs.py --clean
# Show help
python3 scripts/generate-library-docs.py --help
```
### What it does
1. **Parses Rust source files** in `src/syntax/library/functions/` and `src/syntax/library/statements/`
2. **Extracts module documentation** (`//!` comments) from each `.rs` file
3. **Converts markdown to HTML** with syntax highlighting for VB6 code
4. **Generates organized HTML pages**:
- Main library index page
- Category index pages (arrays, math, string, etc.)
- Individual function/statement pages
5. **Creates navigation** with breadcrumbs and cross-links
6. **Builds search index** (`search-index.json`) for client-side search
7. **Applies consistent styling** matching the existing docs site
### Output Structure
```
docs/library/
index.html # Main library reference page
search-index.json # Search data
functions/
arrays/
index.html # Array functions category
array.html # Individual function pages
filter.html
join.html
...
math/
index.html
abs.html
sin.html
...
statements/
file_operations/
index.html
open.html
close.html
...
```
### Generated Content
- **196 total pages**: Main index + category indices + individual item pages
- **161 function pages**: Organized in 14 categories
- **15 statement pages**: Organized in 5 categories
- **Search index**: JSON file with all 176 items for client-side search
### Requirements
- Python 3.6+
- `markdown` library: `pip install markdown`
### Integration
The generated documentation is automatically linked from:
- `docs/index.html` - VB6 Library feature card
- `docs/documentation.html` - Library Reference section
---
## Coverage Generation (`generate-coverage.py`)
### Usage
```bash
# Linux/macOS
./scripts/generate-coverage.py
# Windows
python scripts/generate-coverage.py
# Or with Python3 explicitly
python3 scripts/generate-coverage.py
```
### What it does
1. **Generates coverage data** using `cargo llvm-cov` → saves to `docs/coverage.json`
2. **Counts library tests** using `cargo test --lib --list`
3. **Counts doc tests** using `cargo test --doc --list`
4. **Counts integration tests** by iterating through `tests/*.rs` files
5. **Counts fuzz targets** from `fuzz/fuzz_targets/`
6. **Extracts coverage metrics** from the JSON
7. **Creates stats file** → saves to `docs/stats.json`
### Output Files
#### `docs/coverage.json`
Complete coverage data generated by cargo llvm-cov, including per-file coverage details.
#### `docs/stats.json`
Summary statistics loaded dynamically by the website:
```json
{
"test_count": 5676,
"lib_tests": 5482,
"doc_tests": 99,
"integration_tests": 95,
"fuzz_targets": 9,
"line_coverage": 98.51,
"function_coverage": 93.72,
"region_coverage": 93.59
}
```
### Dynamic Loading
The website automatically loads `stats.json` via JavaScript in `stats.js`:
- Updates `#test-count-header` element (coverage.html header)
- Updates `.test-count` elements (anywhere test counts appear)
- Updates `.test-count-rounded` elements (rounded to hundreds)
- Updates `[data-stat="key"]` elements with matching stat values
### Adding Dynamic Stats
To display any stat value dynamically in HTML:
```html
<span class="test-count">5,676</span>
<span class="test-count-rounded">5,600</span>+
<div data-stat="lib_tests">5,482</div>
<div data-stat="doc_tests">99</div>
<div data-stat="integration_tests">95</div>
<div data-stat="fuzz_targets">9</div>
<div data-stat="line_coverage">98.51</div>
```
The JavaScript will automatically update these with the current values from `stats.json`.
### Requirements
- Rust with cargo
- cargo-llvm-cov (`cargo install cargo-llvm-cov`)
- Python 3.6+ (no external dependencies beyond standard library)
---
## Benchmark Generation (`generate-benchmarks.py`)
### Usage
```bash
./scripts/generate-benchmarks.sh
```
### What it does
1. **Runs benchmarks** using `cargo bench`
2. **Aggregates results** from `target/criterion/**/new/estimates.json`
3. **Extracts metrics** (mean, median, standard deviation)
4. **Creates benchmark file** → saves to `docs/benchmarks.json`
### Output Files
#### `docs/benchmarks.json`
Aggregated benchmark results from all Criterion benchmarks:
```json
{
"benchmarks": [
{
"name": "bulk_parser_load",
"mean": 1234567,
"median": 1234000,
"std_dev": 12345,
"unit": "ns"
}
],
"count": 1
}
```
All timing values are in nanoseconds (ns). The benchmarks.html page automatically converts these to appropriate units (μs, ms, s).
### Viewing Results
Open `docs/benchmarks.html` in a browser or visit the GitHub Pages site. The page displays:
- Summary statistics (total count, average time, fastest/slowest)
- Individual benchmark cards with mean, median, and std dev
- Visual comparison bars
- Search/filter functionality
### Requirements
- Rust with cargo
- Python 3.6+ (no external dependencies beyond standard library)
- Criterion benchmarks configured in `benches/`
---
## GitHub Actions Integration
These Python scripts are designed to work seamlessly in GitHub Actions workflows. They're cross-platform and require no external dependencies beyond Python's standard library.
### Basic Workflow Example
Create a workflow file (e.g., `.github/workflows/docs.yml`) to automatically generate documentation data:
```yaml
name: Generate Documentation Data
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
workflow_dispatch: # Allow manual trigger
jobs:
generate-docs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: 'recursive' # If you have test data in submodules
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Install cargo-llvm-cov
run: cargo install cargo-llvm-cov
- name: Generate coverage data
run: python3 scripts/generate-coverage.py
- name: Generate benchmark data
run: python3 scripts/generate-benchmarks.py
- name: Commit and push if changed
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add docs/coverage.json docs/stats.json docs/benchmarks.json
git diff --quiet && git diff --staged --quiet || git commit -m "Update documentation data [skip ci]"
git push
```
### Separate Coverage and Benchmarks
For larger projects, you may want separate workflows since benchmarks take longer:
#### Coverage Workflow (`.github/workflows/coverage.yml`)
```yaml
name: Generate Coverage
on:
push:
branches: [ main ]
schedule:
- cron: '0 0 * * 0' # Weekly on Sunday at midnight
jobs:
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: 'recursive'
- uses: dtolnay/rust-toolchain@stable
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov
- name: Generate coverage
run: python3 scripts/generate-coverage.py
- name: Upload coverage artifact
uses: actions/upload-artifact@v4
with:
name: coverage-data
path: docs/coverage.json
- name: Upload stats artifact
uses: actions/upload-artifact@v4
with:
name: stats-data
path: docs/stats.json
```
#### Benchmarks Workflow (`.github/workflows/benchmarks.yml`)
```yaml
name: Generate Benchmarks
on:
push:
branches: [ main ]
workflow_dispatch:
jobs:
benchmarks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Generate benchmarks
run: python3 scripts/generate-benchmarks.py
- name: Upload benchmark artifact
uses: actions/upload-artifact@v4
with:
name: benchmark-data
path: docs/benchmarks.json
```
### Deploy to GitHub Pages
Combine generation with automatic deployment to GitHub Pages:
```yaml
name: Deploy Documentation
on:
push:
branches: [ main ]
permissions:
contents: read
pages: write
id-token: write
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: 'recursive'
- uses: dtolnay/rust-toolchain@stable
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov
- name: Generate documentation data
run: |
python3 scripts/generate-coverage.py
python3 scripts/generate-benchmarks.py
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: 'docs'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
```
### Caching for Faster Builds
Speed up your workflow with caching:
```yaml
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo index
uses: actions/cache@v4
with:
path: ~/.cargo/git
key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo build
uses: actions/cache@v4
with:
path: target
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
```
### Running on Multiple Platforms
Test that scripts work on both Linux and Windows:
```yaml
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
# ... setup steps ...
- name: Generate coverage (Unix)
if: runner.os != 'Windows'
run: python3 scripts/generate-coverage.py
- name: Generate coverage (Windows)
if: runner.os == 'Windows'
run: python scripts/generate-coverage.py
```
### Tips for CI Integration
1. **Use `[skip ci]` in commits** - Prevent infinite loops when the workflow commits generated data
2. **Schedule regular runs** - Use `schedule` trigger for weekly/nightly updates
3. **Cache dependencies** - Cache Rust toolchain and cargo artifacts to speed up builds
4. **Separate jobs** - Run coverage and benchmarks in parallel for faster execution
5. **Commit generated files** - GitHub Pages can serve the JSON files directly from the `docs/` folder
6. **Use artifacts** - Upload generated JSON as artifacts for debugging or manual deployment
### Troubleshooting
**Problem:** Script fails with "cargo: command not found"
```yaml
# Solution: Ensure Rust toolchain is installed
- uses: dtolnay/rust-toolchain@stable
```
**Problem:** Script fails with "cargo-llvm-cov: command not found"
```yaml
# Solution: Install cargo-llvm-cov before running coverage script
- uses: taiki-e/install-action@cargo-llvm-cov
# or
- run: cargo install cargo-llvm-cov
```
**Problem:** "Permission denied" when running Python script
```yaml
# Solution: Use python3 explicitly (scripts don't need +x in CI)
- run: python3 scripts/generate-coverage.py
```
**Problem:** Git push fails with authentication error
```yaml
# Solution: Ensure workflow has write permissions
permissions:
contents: write
```