From 033cb4397f03b390a2139012bb58eb7a3d8e4319 Mon Sep 17 00:00:00 2001 From: BrookJeynes Date: Tue, 3 Jun 2025 00:27:20 +1000 Subject: [PATCH] appview,knotserver: include language colour and calculate percentage This commit updates the types related to fetching the languages used within a repo to be more structured and include additional information such as the language colour. Additional logic to calculate the language percentage was added to the repo index. Signed-off-by: BrookJeynes --- appview/pages/pages.go | 2 +- appview/repo/index.go | 66 ++++++++++++++++++++++++++++++++++++++++-- appview/repo/repo.go | 1 + knotserver/routes.go | 5 +++- types/repo.go | 8 ++++- 5 files changed, 77 insertions(+), 5 deletions(-) diff --git a/appview/pages/pages.go b/appview/pages/pages.go index dba91ed..9316c90 100644 --- a/appview/pages/pages.go +++ b/appview/pages/pages.go @@ -446,7 +446,7 @@ type RepoIndexParams struct { Raw bool EmailToDidOrHandle map[string]string VerifiedCommits commitverify.VerifiedCommits - Languages *types.RepoLanguageResponse + Languages []types.RepoLanguageDetails Pipelines map[string]db.Pipeline types.RepoIndexResponse } diff --git a/appview/repo/index.go b/appview/repo/index.go index 061fccd..bb32759 100644 --- a/appview/repo/index.go +++ b/appview/repo/index.go @@ -6,6 +6,7 @@ import ( "log" "net/http" "slices" + "sort" "strings" "tangled.sh/tangled.sh/core/appview/commitverify" @@ -18,6 +19,7 @@ import ( "tangled.sh/tangled.sh/core/types" "github.com/go-chi/chi/v5" + "github.com/go-enry/go-enry/v2" ) func (rp *Repo) RepoIndex(w http.ResponseWriter, r *http.Request) { @@ -121,7 +123,7 @@ func (rp *Repo) RepoIndex(w http.ResponseWriter, r *http.Request) { } } - repoLanguages, err := signedClient.RepoLanguages(f.OwnerDid(), f.RepoName, ref) + languageInfo, err := getLanguageInfo(repoInfo, rp, f, user, signedClient, ref) if err != nil { log.Printf("failed to compute language percentages: %s", err) // non-fatal @@ -148,12 +150,72 @@ func (rp *Repo) RepoIndex(w http.ResponseWriter, r *http.Request) { BranchesTrunc: branchesTrunc, EmailToDidOrHandle: emailToDidOrHandle(rp, emailToDidMap), VerifiedCommits: vc, - Languages: repoLanguages, + Languages: languageInfo, Pipelines: pipelines, }) return } +func getLanguageInfo( + repoInfo repoinfo.RepoInfo, + rp *Repo, + f *reporesolver.ResolvedRepo, + user *oauth.User, + signedClient *knotclient.SignedClient, + ref string, +) ([]types.RepoLanguageDetails, error) { + repoLanguages, err := signedClient.RepoLanguages(f.OwnerDid(), f.RepoName, ref) + if err != nil { + return []types.RepoLanguageDetails{}, err + } + if repoLanguages == nil { + repoLanguages = &types.RepoLanguageResponse{Languages: make(map[string]int)} + } + + totalLanguageFileCount := 0 + for _, fileCount := range repoLanguages.Languages { + totalLanguageFileCount += fileCount + } + + var languageStats []types.RepoLanguageDetails + var otherLanguageStat *types.RepoLanguageDetails + var otherPercentage float32 = 0 + + for fileType, fileCount := range repoLanguages.Languages { + percentage := (float32(fileCount) / float32(totalLanguageFileCount)) * 100 + + if percentage <= 0.1 { + otherPercentage += percentage + continue + } + + // Exclude languages + if fileType == "Text" { + otherPercentage += percentage + continue + } + + color := enry.GetColor(fileType) + + if fileType == "Other" { + otherLanguageStat = &types.RepoLanguageDetails{Name: fileType, Percentage: percentage, Color: color} + } else { + languageStats = append(languageStats, types.RepoLanguageDetails{Name: fileType, Percentage: percentage, Color: color}) + } + } + + sort.Slice(languageStats, func(i, j int) bool { + return languageStats[i].Percentage > languageStats[j].Percentage + }) + + if otherLanguageStat != nil { + otherLanguageStat.Percentage += otherPercentage + languageStats = append(languageStats, *otherLanguageStat) + } + + return languageStats, nil +} + func getForkInfo( repoInfo repoinfo.RepoInfo, rp *Repo, diff --git a/appview/repo/repo.go b/appview/repo/repo.go index 7ac528d..d70d430 100644 --- a/appview/repo/repo.go +++ b/appview/repo/repo.go @@ -35,6 +35,7 @@ import ( securejoin "github.com/cyphar/filepath-securejoin" "github.com/go-chi/chi/v5" + "github.com/go-enry/go-enry/v2" "github.com/go-git/go-git/v5/plumbing" "github.com/posthog/posthog-go" diff --git a/knotserver/routes.go b/knotserver/routes.go index 8b56282..163bd60 100644 --- a/knotserver/routes.go +++ b/knotserver/routes.go @@ -784,10 +784,13 @@ func (h *Handle) RepoLanguages(w http.ResponseWriter, r *http.Request) { content, _ := gr.FileContentN(absPath, 1024) if !safe { lang = enry.GetLanguage(absPath, content) + if len(lang) == 0 { + lang = "Other" + } } else { lang, _ = enry.GetLanguageByContent(absPath, content) if len(lang) == 0 { - return + lang = "Other" } } } diff --git a/types/repo.go b/types/repo.go index 04d7cad..46146e9 100644 --- a/types/repo.go +++ b/types/repo.go @@ -109,7 +109,13 @@ type AncestorCheckResponse struct { Status ForkStatus `json:"status"` } +type RepoLanguageDetails struct { + Name string + Percentage float32 + Color string +} + type RepoLanguageResponse struct { - // Language: Percentage + // Language: File count Languages map[string]int `json:"languages"` } -- 2.51.2