130 lines
2.7 KiB
Go
130 lines
2.7 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/hhatto/gocloc"
|
|
)
|
|
|
|
func main() {
|
|
out, err := exec.Command("git", "ls-files").Output()
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "git ls-files: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
allFiles := strings.Split(strings.TrimSpace(string(out)), "\n")
|
|
|
|
var files []string
|
|
for _, f := range allFiles {
|
|
f = strings.TrimSpace(f)
|
|
if f == "" {
|
|
continue
|
|
}
|
|
norm := filepath.ToSlash(f)
|
|
if strings.HasPrefix(norm, "vendor/") || strings.Contains(norm, "/vendor/") {
|
|
continue
|
|
}
|
|
files = append(files, f)
|
|
}
|
|
|
|
opts := gocloc.NewClocOptions()
|
|
langs := gocloc.NewDefinedLanguages()
|
|
|
|
// gocloc maps "TypeScript" instead of "ts" in its Exts table
|
|
extAliases := map[string]string{
|
|
"ts": "TypeScript",
|
|
}
|
|
|
|
total := gocloc.NewLanguage("TOTAL", []string{}, [][]string{{"", ""}})
|
|
languages := make(map[string]*gocloc.Language)
|
|
clocFiles := make(map[string]*gocloc.ClocFile)
|
|
|
|
for _, file := range files {
|
|
file = strings.TrimSpace(file)
|
|
if file == "" {
|
|
continue
|
|
}
|
|
|
|
ext := filepath.Ext(file)
|
|
if ext == "" {
|
|
continue
|
|
}
|
|
ext = ext[1:]
|
|
|
|
langName, ok := gocloc.Exts[ext]
|
|
if !ok {
|
|
langName, ok = extAliases[ext]
|
|
if !ok {
|
|
continue
|
|
}
|
|
}
|
|
|
|
def := langs.Langs[langName]
|
|
if def == nil {
|
|
continue
|
|
}
|
|
|
|
cf := gocloc.AnalyzeFile(file, def, opts)
|
|
cf.Lang = langName
|
|
clocFiles[file] = cf
|
|
|
|
if _, exists := languages[langName]; !exists {
|
|
languages[langName] = gocloc.NewLanguage(def.Name, []string{}, [][]string{{"", ""}})
|
|
}
|
|
lang := languages[langName]
|
|
lang.Files = append(lang.Files, file)
|
|
lang.Code += cf.Code
|
|
lang.Comments += cf.Comments
|
|
lang.Blanks += cf.Blanks
|
|
|
|
total.Code += cf.Code
|
|
total.Comments += cf.Comments
|
|
total.Blanks += cf.Blanks
|
|
}
|
|
|
|
type row struct {
|
|
Name string
|
|
Files int
|
|
Code int32
|
|
Comments int32
|
|
Blanks int32
|
|
}
|
|
|
|
var rows []row
|
|
for name, lang := range languages {
|
|
rows = append(rows, row{
|
|
Name: name,
|
|
Files: len(lang.Files),
|
|
Code: lang.Code,
|
|
Comments: lang.Comments,
|
|
Blanks: lang.Blanks,
|
|
})
|
|
}
|
|
sort.Slice(rows, func(i, j int) bool {
|
|
return rows[i].Code > rows[j].Code
|
|
})
|
|
|
|
divider := "-------------------------------------------------------------------------------"
|
|
fmt.Println(divider)
|
|
fmt.Printf("%-25s %10s %10s %10s %10s\n", "Language", "Files", "Code", "Comment", "Blank")
|
|
fmt.Println(divider)
|
|
for _, r := range rows {
|
|
fmt.Printf("%-25s %10d %10d %10d %10d\n", r.Name, r.Files, r.Code, r.Comments, r.Blanks)
|
|
}
|
|
fmt.Println(divider)
|
|
fmt.Printf("%-25s %10d %10d %10d %10d\n",
|
|
"Total",
|
|
len(clocFiles),
|
|
total.Code,
|
|
total.Comments,
|
|
total.Blanks,
|
|
)
|
|
fmt.Println(divider)
|
|
}
|