2024-01-02 03:01:45 +00:00
|
|
|
package actions
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/rs/zerolog/log"
|
|
|
|
"github.com/thomiceli/opengist/internal/config"
|
|
|
|
"github.com/thomiceli/opengist/internal/db"
|
|
|
|
"github.com/thomiceli/opengist/internal/git"
|
2024-01-04 02:38:15 +00:00
|
|
|
"github.com/thomiceli/opengist/internal/index"
|
2024-01-02 03:01:45 +00:00
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
|
|
|
"sync"
|
|
|
|
)
|
|
|
|
|
|
|
|
type ActionStatus struct {
|
|
|
|
Running bool
|
|
|
|
}
|
|
|
|
|
|
|
|
const (
|
2024-01-23 19:24:01 +00:00
|
|
|
SyncReposFromFS = iota
|
|
|
|
SyncReposFromDB
|
|
|
|
GitGcRepos
|
|
|
|
SyncGistPreviews
|
|
|
|
ResetHooks
|
|
|
|
IndexGists
|
2024-01-02 03:01:45 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
mutex sync.Mutex
|
|
|
|
actions = make(map[int]ActionStatus)
|
|
|
|
)
|
|
|
|
|
|
|
|
func updateActionStatus(actionType int, running bool) {
|
|
|
|
actions[actionType] = ActionStatus{
|
|
|
|
Running: running,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func IsRunning(actionType int) bool {
|
|
|
|
mutex.Lock()
|
|
|
|
defer mutex.Unlock()
|
|
|
|
return actions[actionType].Running
|
|
|
|
}
|
|
|
|
|
|
|
|
func Run(actionType int) {
|
|
|
|
mutex.Lock()
|
|
|
|
|
|
|
|
if actions[actionType].Running {
|
|
|
|
mutex.Unlock()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
updateActionStatus(actionType, true)
|
|
|
|
mutex.Unlock()
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
mutex.Lock()
|
|
|
|
updateActionStatus(actionType, false)
|
|
|
|
mutex.Unlock()
|
|
|
|
}()
|
|
|
|
|
|
|
|
var functionToRun func()
|
|
|
|
switch actionType {
|
|
|
|
case SyncReposFromFS:
|
|
|
|
functionToRun = syncReposFromFS
|
|
|
|
case SyncReposFromDB:
|
|
|
|
functionToRun = syncReposFromDB
|
|
|
|
case GitGcRepos:
|
|
|
|
functionToRun = gitGcRepos
|
|
|
|
case SyncGistPreviews:
|
|
|
|
functionToRun = syncGistPreviews
|
|
|
|
case ResetHooks:
|
|
|
|
functionToRun = resetHooks
|
2024-01-04 02:38:15 +00:00
|
|
|
case IndexGists:
|
|
|
|
functionToRun = indexGists
|
2024-01-02 03:01:45 +00:00
|
|
|
default:
|
2024-05-27 23:30:08 +00:00
|
|
|
log.Error().Msg("Unknown action type")
|
2024-01-02 03:01:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
functionToRun()
|
|
|
|
}
|
|
|
|
|
|
|
|
func syncReposFromFS() {
|
|
|
|
log.Info().Msg("Syncing repositories from filesystem...")
|
|
|
|
gists, err := db.GetAllGistsRows()
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Err(err).Msg("Cannot get gists")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
for _, gist := range gists {
|
|
|
|
// if repository does not exist, delete gist from database
|
|
|
|
if _, err := os.Stat(git.RepositoryPath(gist.User.Username, gist.Uuid)); err != nil && !os.IsExist(err) {
|
|
|
|
if err2 := gist.Delete(); err2 != nil {
|
|
|
|
log.Error().Err(err2).Msgf("Cannot delete gist %d", gist.ID)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func syncReposFromDB() {
|
|
|
|
log.Info().Msg("Syncing repositories from database...")
|
|
|
|
entries, err := filepath.Glob(filepath.Join(config.GetHomeDir(), "repos", "*", "*"))
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Err(err).Msg("Cannot read repos directories")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, e := range entries {
|
|
|
|
path := strings.Split(e, string(os.PathSeparator))
|
|
|
|
gist, _ := db.GetGist(path[len(path)-2], path[len(path)-1])
|
|
|
|
|
|
|
|
if gist.ID == 0 {
|
|
|
|
if err := git.DeleteRepository(path[len(path)-2], path[len(path)-1]); err != nil {
|
|
|
|
log.Error().Err(err).Msgf("Cannot delete repository %s/%s", path[len(path)-2], path[len(path)-1])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func gitGcRepos() {
|
|
|
|
log.Info().Msg("Garbage collecting all repositories...")
|
|
|
|
if err := git.GcRepos(); err != nil {
|
|
|
|
log.Error().Err(err).Msg("Error garbage collecting repositories")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func syncGistPreviews() {
|
|
|
|
log.Info().Msg("Syncing all Gist previews...")
|
|
|
|
|
|
|
|
gists, err := db.GetAllGistsRows()
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Err(err).Msg("Cannot get gists")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
for _, gist := range gists {
|
|
|
|
if err = gist.UpdatePreviewAndCount(false); err != nil {
|
|
|
|
log.Error().Err(err).Msgf("Cannot update preview and count for gist %d", gist.ID)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func resetHooks() {
|
|
|
|
log.Info().Msg("Resetting Git server hooks for all repositories...")
|
|
|
|
entries, err := filepath.Glob(filepath.Join(config.GetHomeDir(), "repos", "*", "*"))
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Err(err).Msg("Cannot read repos directories")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, e := range entries {
|
|
|
|
path := strings.Split(e, string(os.PathSeparator))
|
|
|
|
if err := git.CreateDotGitFiles(path[len(path)-2], path[len(path)-1]); err != nil {
|
|
|
|
log.Error().Err(err).Msgf("Cannot reset hooks for repository %s/%s", path[len(path)-2], path[len(path)-1])
|
2024-01-04 02:38:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func indexGists() {
|
|
|
|
log.Info().Msg("Indexing all Gists...")
|
|
|
|
gists, err := db.GetAllGistsRows()
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Err(err).Msg("Cannot get gists")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, gist := range gists {
|
|
|
|
log.Info().Msgf("Indexing gist %d", gist.ID)
|
|
|
|
indexedGist, err := gist.ToIndexedGist()
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Err(err).Msgf("Cannot convert gist %d to indexed gist", gist.ID)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if err = index.AddInIndex(indexedGist); err != nil {
|
|
|
|
log.Error().Err(err).Msgf("Cannot index gist %d", gist.ID)
|
2024-01-02 03:01:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|