213 lines
8.1 KiB
Plaintext
Executable File
213 lines
8.1 KiB
Plaintext
Executable File
#!/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
|