provisioning/tools/doc-validator.nu
Jesús Pérez 6a59d34bb1
chore: update provisioning configuration and documentation
Update configuration files, templates, and internal documentation
for the provisioning repository system.

Configuration Updates:
- KMS configuration modernization
- Plugin system settings
- Service port mappings
- Test cluster topologies
- Installation configuration examples
- VM configuration defaults
- Cedar authorization policies

Documentation Updates:
- Library module documentation
- Extension API guides
- AI system documentation
- Service management guides
- Test environment setup
- Plugin usage guides
- Validator configuration documentation

All changes are backward compatible.
2025-12-11 21:50:42 +00:00

216 lines
6.5 KiB
Plaintext
Executable File

#!/usr/bin/env nu
# Documentation Link Validator
# Scans all markdown files and validates internal links
const DOCS_ROOT = "/Users/Akasha/project-provisioning/docs"
const PROVISIONING_DOCS_ROOT = "/Users/Akasha/project-provisioning/provisioning/docs"
# Find all markdown files in documentation
def find-all-docs []: nothing -> list<string> {
let docs_root = "/Users/Akasha/project-provisioning/docs"
let prov_docs_root = "/Users/Akasha/project-provisioning/provisioning/docs"
mut all_docs = []
# Find docs in main docs directory
try {
let main_docs = (glob ($docs_root + "/**/*.md"))
$all_docs = ($all_docs | append $main_docs)
}
# Find docs in provisioning/docs directory
try {
let prov_docs = (glob ($prov_docs_root + "/**/*.md"))
$all_docs = ($all_docs | append $prov_docs)
}
$all_docs | uniq
}
# Extract all markdown links from a file
def extract-links [file: string]: nothing -> table {
let content = (open $file)
let lines = ($content | split row "\n")
mut results = []
for idx in 0..<($lines | length) {
let line = ($lines | get $idx)
# Match markdown links: [text](path)
let matches = ($line | parse -r '\[([^\]]+)\]\(([^)]+)\)')
for match in $matches {
let link_text = ($match | get capture0)
let link_path = ($match | get capture1)
# Classify link type
let link_type = if ($link_path | str starts-with "http") {
"external"
} else if ($link_path | str starts-with "#") {
"anchor"
} else {
"internal"
}
$results = ($results | append {
line: ($idx + 1)
text: $link_text
path: $link_path
type: $link_type
})
}
}
$results
}
# Resolve relative path from source file to target
def resolve-path [source: string, target: string]: nothing -> string {
let source_dir = ($source | path dirname)
# Handle absolute paths
if ($target | str starts-with "/") {
return $target
}
# Handle relative paths
let resolved = ([$source_dir, $target] | path join)
# Normalize path (handle ../ and ./)
$resolved | path expand
}
# Check if a link target exists
def check-link-exists [source: string, link: record]: nothing -> record {
if $link.type == "external" {
return ($link | insert exists true | insert resolved $link.path)
}
if $link.type == "anchor" {
# For now, mark anchors as valid (would need to parse headings to validate)
return ($link | insert exists true | insert resolved $link.path)
}
# Internal link - resolve and check existence
let target_path = (resolve-path $source $link.path)
let exists = ($target_path | path exists)
$link | insert exists $exists | insert resolved $target_path
}
# Validate all links in a file
def validate-file-links [file: string]: nothing -> table {
print $"Checking ($file)..."
let links = (extract-links $file)
$links | each {|link|
let checked = (check-link-exists $file $link)
$checked | insert source_file $file
}
}
# Main validation function
def main [
--fix # Attempt to fix broken links automatically
--format: string = "table" # Output format: table, json, or markdown
] {
print "📚 Documentation Link Validator"
print "================================\n"
print "Finding all documentation files..."
let docs = (find-all-docs)
print $"Found ($docs | length) markdown files\n"
print "Extracting and validating links..."
mut all_results = []
for doc in $docs {
try {
let results = (validate-file-links $doc)
$all_results = ($all_results | append $results)
} catch {|err|
print $"⚠️ Error processing ($doc): ($err.msg)"
}
}
# Summary statistics
let total_links = ($all_results | length)
let internal_links = ($all_results | where type == "internal" | length)
let external_links = ($all_results | where type == "external" | length)
let anchor_links = ($all_results | where type == "anchor" | length)
let broken_links = ($all_results | where exists == false | length)
print "\n📊 Summary Statistics"
print "====================="
print $"Total links found: ($total_links)"
print $" Internal links: ($internal_links)"
print $" External links: ($external_links)"
print $" Anchor links: ($anchor_links)"
print $" Broken links: ❌ ($broken_links)"
# Show broken links if any
if $broken_links > 0 {
print "\n❌ Broken Links Report"
print "======================"
let broken = ($all_results | where exists == false)
if $format == "json" {
$broken | to json
} else if $format == "markdown" {
print "| Source File | Line | Link Text | Target Path |"
print "|-------------|------|-----------|-------------|"
for link in $broken {
print $"| ($link.source_file) | ($link.line) | ($link.text) | ($link.path) |"
}
} else {
$broken | select source_file line text path resolved | table -e
}
# Save broken links report
let report_file = "/Users/Akasha/project-provisioning/provisioning/tools/broken-links-report.json"
$broken | save -f $report_file
print $"\n💾 Broken links report saved to: ($report_file)"
if $fix {
print "\n🔧 Attempting to fix broken links..."
# TODO: Implement auto-fix logic
print "⚠️ Auto-fix not yet implemented"
}
} else {
print "\n✅ All links are valid!"
}
# Save full validation report
let full_report_file = "/Users/Akasha/project-provisioning/provisioning/tools/doc-validation-full-report.json"
$all_results | save -f $full_report_file
print $"\n💾 Full validation report saved to: ($full_report_file)"
# Return exit code based on broken links
if $broken_links > 0 {
exit 1
}
}
# Export utility functions for use in other scripts
export def "links find" [file: string] {
extract-links $file
}
export def "links validate" [file: string] {
validate-file-links $file
}
export def "links check" [source: string, target: string] {
let resolved = (resolve-path $source $target)
{
source: $source
target: $target
resolved: $resolved
exists: ($resolved | path exists)
}
}