provisioning/tools/analyze-codebase.nu

213 lines
8.1 KiB
Plaintext
Raw Normal View History

2025-10-07 11:12:02 +01:00
#!/usr/bin/env nu
# Codebase Technology Analysis Script
# Analyzes provisioning directory for technology distribution
def main [
--path: string = "." # Base path to analyze (default: current directory)
--format: string = "table" # Output format: table, json, markdown
] {
print $"(ansi cyan_bold)📊 Analyzing Codebase(ansi reset)\n"
let base_path = ($path | path expand)
if not ($base_path | path exists) {
print $"(ansi red_bold)Error: Path '($base_path)' does not exist(ansi reset)"
return
}
print $"(ansi grey)Analyzing: ($base_path)(ansi reset)\n"
# Define sections to analyze
let sections = ["core", "extensions", "platform", "templates", "kcl"]
# Analyze each section
let results = ($sections | each { |section|
let section_path = $"($base_path)/($section)"
if ($section_path | path exists) {
{
section: $section
nushell: (count_lines $section_path "nu")
kcl: (count_lines $section_path "k")
rust: (count_lines $section_path "rs")
templates: (count_templates $section_path)
}
} else {
{
section: $section
nushell: 0
kcl: 0
rust: 0
templates: 0
}
}
})
# Calculate totals
let total_nushell = ($results | each { |r| $r.nushell } | math sum)
let total_kcl = ($results | each { |r| $r.kcl } | math sum)
let total_rust = ($results | each { |r| $r.rust } | math sum)
let total_templates = ($results | each { |r| $r.templates } | math sum)
let grand_total = ($total_nushell + $total_kcl + $total_rust + $total_templates)
# Add percentages
let results_with_pct = $results | each { |row|
let section_total = ($row.nushell + $row.kcl + $row.rust + $row.templates)
{
section: $row.section
nushell: $row.nushell
nushell_pct: (if $section_total > 0 { ($row.nushell / $section_total * 100) | math round -p 2 } else { 0 })
kcl: $row.kcl
kcl_pct: (if $section_total > 0 { ($row.kcl / $section_total * 100) | math round -p 2 } else { 0 })
rust: $row.rust
rust_pct: (if $section_total > 0 { ($row.rust / $section_total * 100) | math round -p 2 } else { 0 })
templates: $row.templates
templates_pct: (if $section_total > 0 { ($row.templates / $section_total * 100) | math round -p 2 } else { 0 })
total: $section_total
}
}
# Display results based on format
match $format {
"table" => {
print $"(ansi green_bold)📋 Lines of Code by Section(ansi reset)\n"
$results_with_pct | table -e
print $"\n(ansi yellow_bold)📊 Overall Technology Distribution(ansi reset)\n"
if $grand_total > 0 {
[
{
technology: "Nushell"
lines: $total_nushell
percentage: (($total_nushell / $grand_total * 100) | math round -p 2)
visual: (create_bar ($total_nushell / $grand_total * 100))
}
{
technology: "KCL"
lines: $total_kcl
percentage: (($total_kcl / $grand_total * 100) | math round -p 2)
visual: (create_bar ($total_kcl / $grand_total * 100))
}
{
technology: "Rust"
lines: $total_rust
percentage: (($total_rust / $grand_total * 100) | math round -p 2)
visual: (create_bar ($total_rust / $grand_total * 100))
}
{
technology: "Templates (Tera)"
lines: $total_templates
percentage: (($total_templates / $grand_total * 100) | math round -p 2)
visual: (create_bar ($total_templates / $grand_total * 100))
}
] | table -e
}
print $"\n(ansi cyan_bold)📈 Total Lines of Code: ($grand_total | into string)(ansi reset)"
}
"json" => {
{
sections: $results_with_pct
totals: {
nushell: $total_nushell
kcl: $total_kcl
rust: $total_rust
templates: $total_templates
grand_total: $grand_total
}
percentages: {
nushell: (if $grand_total > 0 { ($total_nushell / $grand_total * 100) | math round -p 2 } else { 0 })
kcl: (if $grand_total > 0 { ($total_kcl / $grand_total * 100) | math round -p 2 } else { 0 })
rust: (if $grand_total > 0 { ($total_rust / $grand_total * 100) | math round -p 2 } else { 0 })
templates: (if $grand_total > 0 { ($total_templates / $grand_total * 100) | math round -p 2 } else { 0 })
}
} | to json
}
"markdown" => {
print "# Codebase Analysis\n"
print "## Technology Distribution\n"
print "| Technology | Lines | Percentage |"
print "|------------|-------|------------|"
print $"| Nushell | ($total_nushell) | (if $grand_total > 0 { ($total_nushell / $grand_total * 100) | math round -p 2 } else { 0 })% |"
print $"| KCL | ($total_kcl) | (if $grand_total > 0 { ($total_kcl / $grand_total * 100) | math round -p 2 } else { 0 })% |"
print $"| Rust | ($total_rust) | (if $grand_total > 0 { ($total_rust / $grand_total * 100) | math round -p 2 } else { 0 })% |"
print $"| Templates | ($total_templates) | (if $grand_total > 0 { ($total_templates / $grand_total * 100) | math round -p 2 } else { 0 })% |"
print $"| **TOTAL** | **($grand_total)** | **100%** |\n"
print "## By Section\n"
print "| Section | Nushell | KCL | Rust | Templates | Total |"
print "|---------|---------|-----|------|-----------|-------|"
$results_with_pct | each { |row|
print $"| ($row.section) | ($row.nushell) | ($row.kcl) | ($row.rust) | ($row.templates) | ($row.total) |"
}
}
_ => {
print $"(ansi red)Unknown format: ($format). Use: table, json, or markdown(ansi reset)"
}
}
}
# Count lines using bash find (more reliable)
def count_lines [path: string, extension: string]: nothing -> int {
let result = (
^find $path -type f -name $"*.($extension)" -exec wc -l {} +
| complete
)
if $result.exit_code != 0 {
return 0
}
let output = ($result.stdout | str trim)
if ($output | is-empty) {
return 0
}
# Get the total from last line
let lines = ($output | lines)
if ($lines | is-empty) {
return 0
}
let last_line = ($lines | last)
if ($last_line | str contains "total") {
let parts = ($last_line | split row " " | where ($it | str trim) != "")
if ($parts | length) > 0 {
$parts | first | into int
} else {
0
}
} else if ($lines | length) == 1 {
# Single file
let parts = ($last_line | split row " " | where ($it | str trim) != "")
if ($parts | length) > 0 {
$parts | first | into int
} else {
0
}
} else {
0
}
}
# Count template lines (.j2 and .tera files)
def count_templates [path: string]: nothing -> int {
let j2 = (count_lines $path "j2")
let tera = (count_lines $path "tera")
$j2 + $tera
}
# Create visual bar chart
def create_bar [percentage: float]: nothing -> string {
let bar_length = ($percentage / 2 | math round) # 50 chars max
let filled = (0..<$bar_length | each { "█" } | str join)
let empty_length = (50 - $bar_length)
let empty = (0..<$empty_length | each { " " } | str join)
$"($filled)($empty) ($percentage | math round -p 1)%"
}
# Export main as the entry point
main