@ -6,6 +6,7 @@ package repo
import (
import (
"context"
"context"
"math"
"math"
"sort"
"strings"
"strings"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/db"
@ -43,7 +44,7 @@ func (stats LanguageStatList) LoadAttributes() {
func ( stats LanguageStatList ) getLanguagePercentages ( ) map [ string ] float32 {
func ( stats LanguageStatList ) getLanguagePercentages ( ) map [ string ] float32 {
langPerc := make ( map [ string ] float32 )
langPerc := make ( map [ string ] float32 )
var otherPerc float32 = 100
var otherPerc float32
var total int64
var total int64
for _ , stat := range stats {
for _ , stat := range stats {
@ -51,21 +52,52 @@ func (stats LanguageStatList) getLanguagePercentages() map[string]float32 {
}
}
if total > 0 {
if total > 0 {
for _ , stat := range stats {
for _ , stat := range stats {
perc := float32 ( math . Round ( float64 ( stat . Size ) / float64 ( total ) * 1000 ) / 1 0 )
perc := float32 ( float64 ( stat . Size ) / float64 ( total ) * 100 )
if perc <= 0.1 {
if perc <= 0.1 {
otherPerc += perc
continue
continue
}
}
otherPerc -= perc
langPerc [ stat . Language ] = perc
langPerc [ stat . Language ] = perc
}
}
otherPerc = float32 ( math . Round ( float64 ( otherPerc ) * 10 ) / 10 )
}
}
if otherPerc > 0 {
if otherPerc > 0 {
langPerc [ "other" ] = otherPerc
langPerc [ "other" ] = otherPerc
}
}
roundByLargestRemainder ( langPerc , 100 )
return langPerc
return langPerc
}
}
// Rounds to 1 decimal point, target should be the expected sum of percs
func roundByLargestRemainder ( percs map [ string ] float32 , target float32 ) {
leftToDistribute := int ( target * 10 )
keys := make ( [ ] string , 0 , len ( percs ) )
for k , v := range percs {
percs [ k ] = v * 10
floored := math . Floor ( float64 ( percs [ k ] ) )
leftToDistribute -= int ( floored )
keys = append ( keys , k )
}
// Sort the keys by the largest remainder
sort . SliceStable ( keys , func ( i , j int ) bool {
_ , remainderI := math . Modf ( float64 ( percs [ keys [ i ] ] ) )
_ , remainderJ := math . Modf ( float64 ( percs [ keys [ j ] ] ) )
return remainderI > remainderJ
} )
// Increment the values in order of largest remainder
for _ , k := range keys {
percs [ k ] = float32 ( math . Floor ( float64 ( percs [ k ] ) ) )
if leftToDistribute > 0 {
percs [ k ] ++
leftToDistribute --
}
percs [ k ] /= 10
}
}
// GetLanguageStats returns the language statistics for a repository
// GetLanguageStats returns the language statistics for a repository
func GetLanguageStats ( ctx context . Context , repo * Repository ) ( LanguageStatList , error ) {
func GetLanguageStats ( ctx context . Context , repo * Repository ) ( LanguageStatList , error ) {
stats := make ( LanguageStatList , 0 , 6 )
stats := make ( LanguageStatList , 0 , 6 )