diff --git a/models/fixtures/language_stat.yml b/models/fixtures/language_stat.yml new file mode 100644 index 0000000000..e18ce8c496 --- /dev/null +++ b/models/fixtures/language_stat.yml @@ -0,0 +1,17 @@ +- + id: 1 + repo_id: 1 + commit_id: 65f1bf27bc3bf70f64657658635e66094edbcb4d + is_primary: true + language: 'Go' + size: 1023 + created_unix: 1779733547 + +- + id: 2 + repo_id: 1 + commit_id: 65f1bf27bc3bf70f64657658635e66094edbcb4d + is_primary: false + language: 'PHP' + size: 1 + created_unix: 1779733547 diff --git a/models/repo/language_stats.go b/models/repo/language_stats.go index 1b619c80cc..9ba2fa5818 100644 --- a/models/repo/language_stats.go +++ b/models/repo/language_stats.go @@ -33,13 +33,18 @@ func init() { db.RegisterModel(new(LanguageStat)) } +// LoadAttributes loads attributes +func (stat *LanguageStat) LoadAttributes() { + stat.Color = enry.GetColor(stat.Language) +} + // LanguageStatList defines a list of language statistics type LanguageStatList []*LanguageStat // LoadAttributes loads attributes func (stats LanguageStatList) LoadAttributes() { for i := range stats { - stats[i].Color = enry.GetColor(stats[i].Language) + stats[i].LoadAttributes() } } diff --git a/models/repo/repo.go b/models/repo/repo.go index 0c45f483e4..79b511b16f 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -293,6 +293,28 @@ func (repo *Repository) AfterLoad() { repo.NumOpenProjects = repo.NumProjects - repo.NumClosedProjects } +// LoadLanguage loads the primary language of the repository, if one exists. +// If one doesn't exists `nil` is still returned. +func (repo *Repository) LoadLanguage(ctx context.Context) error { + if repo.PrimaryLanguage != nil { + return nil + } + + var stat LanguageStat + has, err := db.GetEngine(ctx). + Where("`repo_id` = ? AND `is_primary` = ? AND `language` != ?", repo.ID, true, "other"). + Get(&stat) + if err != nil { + return fmt.Errorf("unable to find the primary languages: %w", err) + } + if has { + stat.LoadAttributes() + repo.PrimaryLanguage = &stat + } + + return nil +} + // LoadAttributes loads attributes of the repository. func (repo *Repository) LoadAttributes(ctx context.Context) error { // Load owner @@ -300,20 +322,11 @@ func (repo *Repository) LoadAttributes(ctx context.Context) error { return fmt.Errorf("load owner: %w", err) } - // Load primary language - stats := make(LanguageStatList, 0, 1) - if err := db.GetEngine(ctx). - Where("`repo_id` = ? AND `is_primary` = ? AND `language` != ?", repo.ID, true, "other"). - Find(&stats); err != nil { - return fmt.Errorf("find primary languages: %w", err) - } - stats.LoadAttributes() - for _, st := range stats { - if st.RepoID == repo.ID { - repo.PrimaryLanguage = st - break - } + // Load the primary language. + if err := repo.LoadLanguage(ctx); err != nil { + return fmt.Errorf("load language: %w", err) } + return nil } diff --git a/modules/indexer/stats/indexer_test.go b/modules/indexer/stats/indexer_test.go index 7d51d3f522..d27bc94985 100644 --- a/modules/indexer/stats/indexer_test.go +++ b/modules/indexer/stats/indexer_test.go @@ -43,5 +43,7 @@ func TestRepoStatsIndex(t *testing.T) { assert.Equal(t, "65f1bf27bc3bf70f64657658635e66094edbcb4d", status.CommitSha) langs, err := repo_model.GetTopLanguageStats(db.DefaultContext, repo, 5) require.NoError(t, err) - assert.Empty(t, langs) + if assert.Len(t, langs, 1) { + assert.Equal(t, &repo_model.LanguageStat{ID: 1, RepoID: 1, CommitID: "65f1bf27bc3bf70f64657658635e66094edbcb4d", IsPrimary: true, Language: "Go", Percentage: 99.9, Size: 1023, Color: "#00ADD8", CreatedUnix: 1779733547}, langs[0]) + } } diff --git a/services/convert/repository.go b/services/convert/repository.go index b95e7675a8..bf3e136e8f 100644 --- a/services/convert/repository.go +++ b/services/convert/repository.go @@ -173,6 +173,10 @@ func innerToRepo(ctx stdCtx.Context, repo *repo_model.Repository, permissionInRe } } + if err := repo.LoadLanguage(ctx); err != nil { + log.Warn("Unable to load language for repo[id=%d]: %w", repo.ID, err) + } + var language string if repo.PrimaryLanguage != nil { language = repo.PrimaryLanguage.Language diff --git a/tests/integration/api_user_star_test.go b/tests/integration/api_user_star_test.go index 1e6b4400ae..ce0b24d0e3 100644 --- a/tests/integration/api_user_star_test.go +++ b/tests/integration/api_user_star_test.go @@ -63,6 +63,7 @@ func TestAPIStar(t *testing.T) { DecodeJSON(t, resp, &repos) assert.Len(t, repos, 1) assert.Equal(t, repo, repos[0].FullName) + assert.Equal(t, "Go", repos[0].Language) t.Run("disabled stars", func(t *testing.T) { assertDisabledStarsNotFound(t, req) @@ -82,6 +83,7 @@ func TestAPIStar(t *testing.T) { DecodeJSON(t, resp, &repos) assert.Len(t, repos, 1) assert.Equal(t, repo, repos[0].FullName) + assert.Equal(t, "Go", repos[0].Language) t.Run("disabled stars", func(t *testing.T) { assertDisabledStarsNotFound(t, req)