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-27 01:12:30
Commitcfc2b79df71292d2b6c6463bcf1bf9e484b395b7
Parent20732d36486576a28971edc4b0b94b050805faae

Calculate directory size in tree view

Diffstat

M src/admin.go | 2 +-
M src/repo.go | 33 ---------------------------------
M src/repo/tree.go | 20 ++++++++++++++++++++
M src/util/util.go | 38 ++++++++++++++++++++++++++++++++++++++

4 files changed, 59 insertions, 34 deletions

diff --git a/src/admin.go b/src/admin.go
index 3af6822..701317b 100644
--- a/src/admin.go
+++ b/src/admin.go
@@ -228,7 +228,7 @@ func HandleAdminRepos(w http.ResponseWriter, r *http.Request) {
 			log.Println("[/admin/repos]", err.Error())
 		}
 
-		size, err := RepoSize(d.Name)
+		size, err := util.DirSize(RepoPath(d.Name))
 		if err != nil {
 			log.Println("[/admin/repos]", err.Error())
 		}
diff --git a/src/repo.go b/src/repo.go
index f6ea254..7cc9780 100644
--- a/src/repo.go
+++ b/src/repo.go
@@ -10,7 +10,6 @@ import (
 	"log"
 	"net/http"
 	"os"
-	"path/filepath"
 	"strings"
 
 	"github.com/Jamozed/Goit/src/util"
@@ -226,35 +225,3 @@ func RepoExists(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
-}
diff --git a/src/repo/tree.go b/src/repo/tree.go
index 3bd72fa..5a91496 100644
--- a/src/repo/tree.go
+++ b/src/repo/tree.go
@@ -105,6 +105,26 @@ func HandleTree(w http.ResponseWriter, r *http.Request) {
 				}
 
 				size = humanize.IBytes(uint64(file.Size))
+			} else {
+				var dirSize uint64
+
+				dirt, err := tree.Tree(v.Name)
+				if err != nil {
+					log.Println("[/repo/tree]", err.Error())
+					goit.HttpError(w, http.StatusInternalServerError)
+					return
+				}
+
+				if err := dirt.Files().ForEach(func(f *object.File) error {
+					dirSize += uint64(f.Size)
+					return nil
+				}); err != nil {
+					log.Println("[/repo/tree]", err.Error())
+					goit.HttpError(w, http.StatusInternalServerError)
+					return
+				}
+
+				size = humanize.IBytes(dirSize)
 			}
 
 			data.Files = append(data.Files, row{
diff --git a/src/util/util.go b/src/util/util.go
index e16f483..ca55333 100644
--- a/src/util/util.go
+++ b/src/util/util.go
@@ -5,9 +5,16 @@
 package util
 
 import (
+	"errors"
+	"io/fs"
 	"net/http"
+	"os"
+	"path/filepath"
 )
 
+const ModeNotRegular = os.ModeSymlink | os.ModeDevice | os.ModeNamedPipe | os.ModeSocket | os.ModeCharDevice |
+	os.ModeIrregular
+
 func If[T any](cond bool, a, b T) T {
 	if cond {
 		return a
@@ -49,3 +56,34 @@ func ModeString(mode uint32) string {
 	s += If((mode&0o001) != 0, "x", "-")
 	return s
 }
+
+func DirSize(path string) (uint64, error) {
+	var size int64
+
+	err := filepath.WalkDir(path, func(_ string, d fs.DirEntry, err error) error {
+		if err != nil {
+			if errors.Is(err, os.ErrNotExist) {
+				return nil
+			}
+
+			return err
+		}
+
+		if d.IsDir() {
+			return nil
+		}
+
+		f, err := d.Info()
+		if err != nil {
+			return err
+		}
+
+		if (f.Mode() & ModeNotRegular) == 0 {
+			size += f.Size()
+		}
+
+		return nil
+	})
+
+	return uint64(size), err
+}