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