Skip to content

Repo size in admin panel #1482

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 11, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions models/migrations/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ var migrations = []Migration{
NewMigration("generate and migrate repo and wiki Git hooks", generateAndMigrateGitHookChains),
// v27 -> v28
NewMigration("change mirror interval from hours to time.Duration", convertIntervalToDuration),
// v28 -> v29
NewMigration("add field for repo size", addRepoSize),
}

// Migrate database to current version
Expand Down
77 changes: 77 additions & 0 deletions models/migrations/v28.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright 2017 The Gogs Authors. All rights reserved.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

porting from Gogs?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the migration is straight from Gogs.

// Copyright 2017 Gitea. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package migrations

import (
"fmt"
"path/filepath"
"strings"

"code.gitea.io/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"

"github.com/go-xorm/xorm"
)

func addRepoSize(x *xorm.Engine) (err error) {
log.Info("This migration could take up to minutes, please be patient.")
type Repository struct {
ID int64
OwnerID int64
Name string
Size int64
}
type User struct {
ID int64
Name string
}
if err = x.Sync2(new(Repository)); err != nil {
return fmt.Errorf("Sync2: %v", err)
}

// For the sake of SQLite3, we can't use x.Iterate here.
offset := 0
for {
repos := make([]*Repository, 0, 10)
if err = x.Sql(fmt.Sprintf("SELECT * FROM `repository` ORDER BY id ASC LIMIT 10 OFFSET %d", offset)).
Find(&repos); err != nil {
return fmt.Errorf("select repos [offset: %d]: %v", offset, err)
}
log.Trace("Select [offset: %d, repos: %d]", offset, len(repos))
if len(repos) == 0 {
break
}
offset += 10

for _, repo := range repos {
if repo.Name == "." || repo.Name == ".." {
continue
}

user := new(User)
has, err := x.Where("id = ?", repo.OwnerID).Get(user)
if err != nil {
return fmt.Errorf("query owner of repository [repo_id: %d, owner_id: %d]: %v", repo.ID, repo.OwnerID, err)
} else if !has {
continue
}

repoPath := filepath.Join(setting.RepoRootPath, strings.ToLower(user.Name), strings.ToLower(repo.Name)) + ".git"
countObject, err := git.GetRepoSize(repoPath)
if err != nil {
log.Warn("GetRepoSize: %v", err)
continue
}

repo.Size = countObject.Size + countObject.SizePack
if _, err = x.Id(repo.ID).Cols("size").Update(repo); err != nil {
return fmt.Errorf("update size: %v", err)
}
}
}
return nil
}
25 changes: 25 additions & 0 deletions models/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ type Repository struct {
IsFork bool `xorm:"INDEX NOT NULL DEFAULT false"`
ForkID int64 `xorm:"INDEX"`
BaseRepo *Repository `xorm:"-"`
Size int64 `xorm:"NOT NULL DEFAULT 0"`

Created time.Time `xorm:"-"`
CreatedUnix int64 `xorm:"INDEX"`
Expand Down Expand Up @@ -546,6 +547,18 @@ func (repo *Repository) IsOwnedBy(userID int64) bool {
return repo.OwnerID == userID
}

// UpdateSize updates the repository size, calculating it using git.GetRepoSize
func (repo *Repository) UpdateSize() error {
repoInfoSize, err := git.GetRepoSize(repo.RepoPath())
if err != nil {
return fmt.Errorf("UpdateSize: %v", err)
}

repo.Size = repoInfoSize.Size + repoInfoSize.SizePack
_, err = x.ID(repo.ID).Cols("size").Update(repo)
return err
}

// CanBeForked returns true if repository meets the requirements of being forked.
func (repo *Repository) CanBeForked() bool {
return !repo.IsBare
Expand Down Expand Up @@ -810,6 +823,10 @@ func MigrateRepository(u *User, opts MigrateRepoOptions) (*Repository, error) {
}
}

if err = repo.UpdateSize(); err != nil {
log.Error(4, "Failed to update size for repository: %v", err)
}

if opts.IsMirror {
if _, err = x.InsertOne(&Mirror{
RepoID: repo.ID,
Expand Down Expand Up @@ -1464,6 +1481,10 @@ func updateRepository(e Engine, repo *Repository, visibilityChanged bool) (err e
return fmt.Errorf("updateRepository[%d]: %v", forkRepos[i].ID, err)
}
}

if err = repo.UpdateSize(); err != nil {
log.Error(4, "Failed to update size for repository: %v", err)
}
}

return nil
Expand Down Expand Up @@ -2171,6 +2192,10 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Reposit
return nil, err
}

if err = repo.UpdateSize(); err != nil {
log.Error(4, "Failed to update size for repository: %v", err)
}

// Copy LFS meta objects in new session
sess2 := x.NewSession()
defer sessionRelease(sess2)
Expand Down
5 changes: 5 additions & 0 deletions models/repo_mirror.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,11 @@ func (m *Mirror) runSync() bool {
}
return false
}

if err := m.Repo.UpdateSize(); err != nil {
log.Error(4, "Failed to update size for mirror repository: %v", err)
}

if m.Repo.HasWiki() {
if _, stderr, err := process.GetManager().ExecDir(
timeout, wikiPath, fmt.Sprintf("Mirror.runSync: %s", wikiPath),
Expand Down
4 changes: 4 additions & 0 deletions models/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ func PushUpdate(opts PushUpdateOptions) (err error) {
return fmt.Errorf("GetRepositoryByName: %v", err)
}

if err = repo.UpdateSize(); err != nil {
log.Error(4, "Failed to update size for repository: %v", err)
}

// Push tags.
if strings.HasPrefix(opts.RefFullName, git.TagPrefix) {
if err := CommitRepoAction(CommitRepoActionOptions{
Expand Down
3 changes: 3 additions & 0 deletions modules/templates/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ func NewFuncMap() []template.FuncMap {
"DateFmtShort": func(t time.Time) string {
return t.Format("Jan 02, 2006")
},
"SizeFmt": func(s int64) string {
return base.FileSize(s)
},
"List": List,
"SubStr": func(str string, start, length int) string {
if len(str) == 0 {
Expand Down
1 change: 1 addition & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,7 @@ repos.private = Private
repos.watches = Watches
repos.stars = Stars
repos.issues = Issues
repos.size = Size

auths.auth_manage_panel = Authentication Manage Panel
auths.new = Add New Source
Expand Down
2 changes: 2 additions & 0 deletions templates/admin/repo/list.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<th>{{.i18n.Tr "admin.repos.watches"}}</th>
<th>{{.i18n.Tr "admin.repos.stars"}}</th>
<th>{{.i18n.Tr "admin.repos.issues"}}</th>
<th>{{.i18n.Tr "admin.repos.size"}}</th>
<th>{{.i18n.Tr "admin.users.created"}}</th>
<th>{{.i18n.Tr "admin.notices.op"}}</th>
</tr>
Expand All @@ -34,6 +35,7 @@
<td>{{.NumWatches}}</td>
<td>{{.NumStars}}</td>
<td>{{.NumIssues}}</td>
<td>{{SizeFmt .Size}}</td>
<td><span title="{{DateFmtLong .Created}}">{{DateFmtShort .Created}}</span></td>
<td><a class="delete-button" href="" data-url="{{$.Link}}/delete?page={{$.Page.Current}}" data-id="{{.ID}}"><i class="trash icon text red"></i></a></td>
</tr>
Expand Down