1package git
2
3import (
4 "context"
5 "path"
6
7 "github.com/go-enry/go-enry/v2"
8 "github.com/go-git/go-git/v5/plumbing/object"
9)
10
11type LangBreakdown map[string]int64
12
13func (g *GitRepo) AnalyzeLanguages(ctx context.Context) (LangBreakdown, error) {
14 sizes := make(map[string]int64)
15 err := g.Walk(ctx, "", func(node object.TreeEntry, parent *object.Tree, root string) error {
16 filepath := path.Join(root, node.Name)
17
18 content, err := g.FileContentN(filepath, 16*1024) // 16KB
19 if err != nil {
20 return nil
21 }
22
23 if enry.IsGenerated(filepath, content) {
24 return nil
25 }
26
27 language := analyzeLanguage(node, content)
28 if group := enry.GetLanguageGroup(language); group != "" {
29 language = group
30 }
31
32 langType := enry.GetLanguageType(language)
33 if langType != enry.Programming && langType != enry.Markup && langType != enry.Unknown {
34 return nil
35 }
36
37 sz, _ := parent.Size(node.Name)
38 sizes[language] += sz
39
40 return nil
41 })
42
43 if err != nil {
44 return nil, err
45 }
46
47 return sizes, nil
48}
49
50func analyzeLanguage(node object.TreeEntry, content []byte) string {
51 language, ok := enry.GetLanguageByExtension(node.Name)
52 if ok {
53 return language
54 }
55
56 language, ok = enry.GetLanguageByFilename(node.Name)
57 if ok {
58 return language
59 }
60
61 if len(content) == 0 {
62 return enry.OtherLanguage
63 }
64
65 return enry.GetLanguage(node.Name, content)
66}