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.
216 lines
6.5 KiB
Plaintext
Executable File
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)
|
|
}
|
|
}
|