···
securejoin "github.com/cyphar/filepath-securejoin"
"github.com/gliderlabs/ssh"
···
func (h *Handle) RepoLanguages(w http.ResponseWriter, r *http.Request) {
766
-
path, _ := securejoin.SecureJoin(h.c.Repo.ScanPath, didPath(r))
767
+
repoPath, _ := securejoin.SecureJoin(h.c.Repo.ScanPath, didPath(r))
ref := chi.URLParam(r, "ref")
ref, _ = url.PathUnescape(ref)
l := h.l.With("handler", "RepoLanguages")
772
-
gr, err := git.Open(path, ref)
773
+
gr, err := git.Open(repoPath, ref)
l.Error("opening repo", "error", err.Error())
779
-
languageFileCount := make(map[string]int)
780
+
sizes := make(map[string]int64)
781
-
err = recurseEntireTree(r.Context(), gr, func(absPath string) {
782
-
lang, safe := enry.GetLanguageByExtension(absPath)
783
-
if len(lang) == 0 || !safe {
784
-
content, _ := gr.FileContentN(absPath, 1024)
786
-
lang = enry.GetLanguage(absPath, content)
787
-
if len(lang) == 0 {
791
-
lang, _ = enry.GetLanguageByContent(absPath, content)
792
-
if len(lang) == 0 {
782
+
ctx, cancel := context.WithTimeout(r.Context(), 1*time.Second)
785
+
err = gr.Walk(ctx, "", func(node object.TreeEntry, parent *object.Tree, root string) error {
786
+
filepath := path.Join(root, node.Name)
788
+
content, err := gr.FileContentN(filepath, 16*1024) // 16KB
798
-
v, ok := languageFileCount[lang]
800
-
languageFileCount[lang] = v + 1
802
-
languageFileCount[lang] = 1
793
+
if enry.IsGenerated(filepath, content) {
797
+
language := analyzeLanguage(node, content)
798
+
if group := enry.GetLanguageGroup(language); group != "" {
802
+
langType := enry.GetLanguageType(language)
803
+
if langType != enry.Programming && langType != enry.Markup && langType != enry.Unknown {
807
+
sz, _ := parent.Size(node.Name)
808
+
sizes[language] += sz
l.Error("failed to recurse file tree", "error", err.Error())
writeError(w, err.Error(), http.StatusNoContent)
811
-
resp := types.RepoLanguageResponse{Languages: languageFileCount}
818
+
resp := types.RepoLanguageResponse{Languages: sizes}
817
-
func recurseEntireTree(ctx context.Context, git *git.GitRepo, callback func(absPath string), filePath string) error {
818
-
files, err := git.FileTree(ctx, filePath)
824
+
func analyzeLanguage(node object.TreeEntry, content []byte) string {
825
+
language, ok := enry.GetLanguageByExtension(node.Name)
824
-
for _, file := range files {
825
-
absPath := path.Join(filePath, file.Name)
827
-
return recurseEntireTree(ctx, git, callback, absPath)
830
+
language, ok = enry.GetLanguageByFilename(node.Name)
835
+
if len(content) == 0 {
836
+
return enry.OtherLanguage
839
+
return enry.GetLanguage(node.Name, content)
func (h *Handle) RepoForkSync(w http.ResponseWriter, r *http.Request) {