Goit

Simple and lightweight Git web server
git clone http://git.omkov.net/Goit
Log | Tree | Refs | README | Download

AuthorJakob Wakeling <[email protected]>
Date2023-07-20 12:47:21
Commit4a160dd13c06c4a572a55de208200f686a771eaf
Parentd631c5e22bf3af99f9be0e9cd8d8ea9ca0c14505

Add size to admin repository list

Diffstat

M go.mod | 1 +
M go.sum | 2 ++
M main.go | 2 +-
M src/admin.go | 10 ++++++++--
M src/git.go | 4 ++--
M src/goit.go | 4 ++--
M src/repo.go | 38 ++++++++++++++++++++++++++++++++++++--

7 files changed, 52 insertions, 9 deletions

diff --git a/go.mod b/go.mod
index e1748a3..9bd7e89 100644
--- a/go.mod
+++ b/go.mod
@@ -4,6 +4,7 @@ go 1.20
 
 require (
 	github.com/adrg/xdg v0.4.0
+	github.com/dustin/go-humanize v1.0.1
 	github.com/go-git/go-git/v5 v5.7.0
 	github.com/gorilla/mux v1.8.0
 	github.com/mattn/go-sqlite3 v1.14.17
diff --git a/go.sum b/go.sum
index 6036ded..6a99376 100644
--- a/go.sum
+++ b/go.sum
@@ -16,6 +16,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
+github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
 github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819 h1:RIB4cRk+lBqKK3Oy0r2gRX4ui7tuhiZq2SuTtTCi0/0=
 github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
 github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
diff --git a/main.go b/main.go
index 36a08f7..1bb34eb 100644
--- a/main.go
+++ b/main.go
@@ -16,7 +16,7 @@ import (
 )
 
 func main() {
-	if err := goit.Goit(goit.GetConfPath()); err != nil {
+	if err := goit.Goit(goit.ConfPath()); err != nil {
 		log.Fatalln(err.Error())
 	}
 
diff --git a/src/admin.go b/src/admin.go
index 45006c1..0c6199a 100644
--- a/src/admin.go
+++ b/src/admin.go
@@ -12,6 +12,7 @@ import (
 	"strings"
 
 	"github.com/Jamozed/Goit/src/util"
+	"github.com/dustin/go-humanize"
 )
 
 func HandleAdminUsers(w http.ResponseWriter, r *http.Request) {
@@ -198,7 +199,7 @@ func HandleAdminRepos(w http.ResponseWriter, r *http.Request) {
 	data := struct {
 		Title string
 		Repos []row
-	}{Title: "Repos"}
+	}{Title: "Repositories"}
 
 	for rows.Next() {
 		d := Repo{}
@@ -213,8 +214,13 @@ func HandleAdminRepos(w http.ResponseWriter, r *http.Request) {
 			log.Println("[/admin/repos]", err.Error())
 		}
 
+		size, err := RepoSize(d.Name)
+		if err != nil {
+			log.Println("[/admin/repos]", err.Error())
+		}
+
 		data.Repos = append(data.Repos, row{
-			fmt.Sprint(d.Id), user.Name, d.Name, util.If(d.IsPrivate, "private", "public"), "",
+			fmt.Sprint(d.Id), user.Name, d.Name, util.If(d.IsPrivate, "private", "public"), humanize.IBytes(size),
 		})
 	}
 
diff --git a/src/git.go b/src/git.go
index bef8f2d..c1cb30a 100644
--- a/src/git.go
+++ b/src/git.go
@@ -36,7 +36,7 @@ func HandleInfoRefs(w http.ResponseWriter, r *http.Request) {
 	c := newCommand(strings.TrimPrefix(service, "git-"), "--stateless-rpc", "--advertise-refs", ".")
 	c.addEnv(os.Environ()...)
 	c.addEnv("GIT_PROTOCOL=version=2")
-	c.dir = GetRepoPath(repo.Name)
+	c.dir = RepoPath(repo.Name)
 
 	refs, _, err := c.run(nil, nil)
 	if err != nil {
@@ -163,7 +163,7 @@ func gitHttpRpc(w http.ResponseWriter, r *http.Request, service string, repo *Re
 
 	c := newCommand(strings.TrimPrefix(service, "git-"), "--stateless-rpc", ".")
 	c.addEnv(os.Environ()...)
-	c.dir = GetRepoPath(repo.Name)
+	c.dir = RepoPath(repo.Name)
 
 	if p := r.Header.Get("Git-Protocol"); p == "version=2" {
 		c.addEnv("GIT_PROTOCOL=version=2")
diff --git a/src/goit.go b/src/goit.go
index b9b21e3..f9cb765 100644
--- a/src/goit.go
+++ b/src/goit.go
@@ -108,7 +108,7 @@ func Goit(conf string) (err error) {
 	return nil
 }
 
-func GetConfPath() string {
+func ConfPath() string {
 	if p, err := xdg.SearchConfigFile(path.Join("goit", "goit.json")); err != nil {
 		log.Println("[Config]", err.Error())
 		return ""
@@ -117,6 +117,6 @@ func GetConfPath() string {
 	}
 }
 
-func GetRepoPath(name string) string {
+func RepoPath(name string) string {
 	return path.Join(Conf.DataPath, "repos", name+".git")
 }
diff --git a/src/repo.go b/src/repo.go
index 8ed70f0..0f0614b 100644
--- a/src/repo.go
+++ b/src/repo.go
@@ -9,6 +9,8 @@ import (
 	"errors"
 	"log"
 	"net/http"
+	"os"
+	"path/filepath"
 	"strings"
 	"time"
 
@@ -115,7 +117,7 @@ func HandleRepoLog(w http.ResponseWriter, r *http.Request) {
 	type row struct{ Date, Message, Author string }
 	commits := []row{}
 
-	if gr, err := git.PlainOpen(GetRepoPath(reponame)); err != nil {
+	if gr, err := git.PlainOpen(RepoPath(reponame)); err != nil {
 		log.Println("[Repo:Log]", err.Error())
 		HttpError(w, http.StatusInternalServerError)
 		return
@@ -170,7 +172,7 @@ func HandleRepoRefs(w http.ResponseWriter, r *http.Request) {
 	bras := []bra{}
 	tags := []tag{}
 
-	if gr, err := git.PlainOpen(GetRepoPath(reponame)); err != nil {
+	if gr, err := git.PlainOpen(RepoPath(reponame)); err != nil {
 		log.Println("[Repo:Refs]", err.Error())
 		HttpError(w, http.StatusInternalServerError)
 		return
@@ -238,3 +240,35 @@ func RepoExists(db *sql.DB, name string) (bool, error) {
 		return true, nil
 	}
 }
+
+func RepoSize(name string) (uint64, error) {
+	var size int64
+
+	err := filepath.WalkDir(RepoPath(name), func(_ string, d os.DirEntry, err error) error {
+		if err != nil {
+			if errors.Is(err, os.ErrNotExist) {
+				return nil
+			} else {
+				return err
+			}
+		}
+
+		if d.IsDir() {
+			return nil
+		}
+
+		f, err := d.Info()
+		if err != nil {
+			return err
+		}
+
+		/* Only count the size of regular files */
+		if (f.Mode() & (os.ModeSymlink | os.ModeDevice | os.ModeNamedPipe | os.ModeSocket | os.ModeCharDevice | os.ModeIrregular)) == 0 {
+			size += f.Size()
+		}
+
+		return nil
+	})
+
+	return uint64(size), err
+}