Monorepo for Tangled tangled.org

knotserver/git: refactor language breakdown logic

Signed-off-by: oppiliappan <me@oppi.li>

oppi.li bdeff31f f4ec8829

verified
Changed files
+68 -51
knotserver
+66
knotserver/git/language.go
··· 1 + package git 2 + 3 + import ( 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 + 11 + type LangBreakdown map[string]int64 12 + 13 + func (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 + 50 + func 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 + }
+2 -51
knotserver/routes.go
··· 13 13 "net/http" 14 14 "net/url" 15 15 "os" 16 - "path" 17 16 "path/filepath" 18 17 "strconv" 19 18 "strings" ··· 23 22 securejoin "github.com/cyphar/filepath-securejoin" 24 23 "github.com/gliderlabs/ssh" 25 24 "github.com/go-chi/chi/v5" 26 - "github.com/go-enry/go-enry/v2" 27 25 gogit "github.com/go-git/go-git/v5" 28 26 "github.com/go-git/go-git/v5/plumbing" 29 27 "github.com/go-git/go-git/v5/plumbing/object" ··· 777 775 return 778 776 } 779 777 780 - sizes := make(map[string]int64) 781 - 782 778 ctx, cancel := context.WithTimeout(r.Context(), 1*time.Second) 783 779 defer cancel() 784 780 785 - err = gr.Walk(ctx, "", func(node object.TreeEntry, parent *object.Tree, root string) error { 786 - filepath := path.Join(root, node.Name) 787 - 788 - content, err := gr.FileContentN(filepath, 16*1024) // 16KB 789 - if err != nil { 790 - return nil 791 - } 792 - 793 - if enry.IsGenerated(filepath, content) { 794 - return nil 795 - } 796 - 797 - language := analyzeLanguage(node, content) 798 - if group := enry.GetLanguageGroup(language); group != "" { 799 - language = group 800 - } 801 - 802 - langType := enry.GetLanguageType(language) 803 - if langType != enry.Programming && langType != enry.Markup && langType != enry.Unknown { 804 - return nil 805 - } 806 - 807 - sz, _ := parent.Size(node.Name) 808 - sizes[language] += sz 809 - 810 - return nil 811 - }) 781 + sizes, err := gr.AnalyzeLanguages(ctx) 812 782 if err != nil { 813 - l.Error("failed to recurse file tree", "error", err.Error()) 783 + l.Error("failed to analyze languages", "error", err.Error()) 814 784 writeError(w, err.Error(), http.StatusNoContent) 815 785 return 816 786 } ··· 818 788 resp := types.RepoLanguageResponse{Languages: sizes} 819 789 820 790 writeJSON(w, resp) 821 - return 822 - } 823 - 824 - func analyzeLanguage(node object.TreeEntry, content []byte) string { 825 - language, ok := enry.GetLanguageByExtension(node.Name) 826 - if ok { 827 - return language 828 - } 829 - 830 - language, ok = enry.GetLanguageByFilename(node.Name) 831 - if ok { 832 - return language 833 - } 834 - 835 - if len(content) == 0 { 836 - return enry.OtherLanguage 837 - } 838 - 839 - return enry.GetLanguage(node.Name, content) 840 791 } 841 792 842 793 func (h *Handle) RepoForkSync(w http.ResponseWriter, r *http.Request) {