diff --git a/internal/git/commands.go b/internal/git/commands.go index c93b70fe..57c99899 100644 --- a/internal/git/commands.go +++ b/internal/git/commands.go @@ -2,6 +2,7 @@ package git import ( "fmt" + "github.com/rs/zerolog/log" "github.com/thomiceli/opengist/internal/config" "os" "os/exec" @@ -263,6 +264,47 @@ func RPC(user string, gist string, service string) ([]byte, error) { return stdout, err } +func GcRepos() error { + subdirs, err := os.ReadDir(filepath.Join(config.GetHomeDir(), "repos")) + if err != nil { + return err + } + + for _, subdir := range subdirs { + if !subdir.IsDir() { + continue + } + + subRoot := filepath.Join(config.GetHomeDir(), "repos", subdir.Name()) + + gitRepos, err := os.ReadDir(subRoot) + if err != nil { + log.Warn().Err(err).Msg("Cannot read directory") + continue + } + + for _, repo := range gitRepos { + if !repo.IsDir() { + continue + } + + repoPath := filepath.Join(subRoot, repo.Name()) + + log.Info().Msg("Running git gc for repository " + repoPath) + + cmd := exec.Command("git", "gc") + cmd.Dir = repoPath + err = cmd.Run() + if err != nil { + log.Warn().Err(err).Msg("Cannot run git gc for repository " + repoPath) + continue + } + } + } + + return err +} + func GetGitVersion() (string, error) { cmd := exec.Command("git", "--version") stdout, err := cmd.Output() diff --git a/internal/web/admin.go b/internal/web/admin.go index c218e134..444b4a06 100644 --- a/internal/web/admin.go +++ b/internal/web/admin.go @@ -16,6 +16,7 @@ import ( var ( syncReposFromFS = false syncReposFromDB = false + gitGcRepos = false ) func adminIndex(ctx echo.Context) error { @@ -51,6 +52,7 @@ func adminIndex(ctx echo.Context) error { setData(ctx, "syncReposFromFS", syncReposFromFS) setData(ctx, "syncReposFromDB", syncReposFromDB) + setData(ctx, "gitGcRepos", gitGcRepos) return html(ctx, "admin_index.html") } @@ -185,6 +187,23 @@ func adminSyncReposFromDB(ctx echo.Context) error { return redirect(ctx, "/admin-panel") } +func adminGcRepos(ctx echo.Context) error { + addFlash(ctx, "Garbage collecting repositories...", "success") + go func() { + if gitGcRepos { + return + } + gitGcRepos = true + if err := git.GcRepos(); err != nil { + log.Error().Err(err).Msg("Error garbage collecting repositories") + gitGcRepos = false + return + } + gitGcRepos = false + }() + return redirect(ctx, "/admin-panel") +} + func adminConfig(ctx echo.Context) error { setData(ctx, "title", "Configuration") setData(ctx, "htmlTitle", "Configuration - Admin panel") diff --git a/internal/web/run.go b/internal/web/run.go index 169889ad..4fb827f9 100644 --- a/internal/web/run.go +++ b/internal/web/run.go @@ -204,6 +204,7 @@ func Start() { g2.POST("/gists/:gist/delete", adminGistDelete) g2.POST("/sync-fs", adminSyncReposFromFS) g2.POST("/sync-db", adminSyncReposFromDB) + g2.POST("/gc-repos", adminGcRepos) g2.GET("/configuration", adminConfig) g2.PUT("/set-config", adminSetConfig) } diff --git a/templates/pages/admin_index.html b/templates/pages/admin_index.html index 27e9d690..339b8782 100644 --- a/templates/pages/admin_index.html +++ b/templates/pages/admin_index.html @@ -68,6 +68,12 @@ Synchronize gists from database +