mappu
90cd2b6440
For codesite-migrated repositories, looking at the oldest commit is preferable to determine the "create date". But for forked projects, looking at the oldest commit is incorrect for when we started the project If inferring the real create date has to be manual, then let's rely on the Gitea metadata - it's faster and can be modified by hand if needed
111 lines
2.3 KiB
Go
111 lines
2.3 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"sort"
|
|
"time"
|
|
)
|
|
|
|
func (this *Application) sync(ctx context.Context) (bool, error) {
|
|
|
|
// List repositories on Gitea
|
|
repos, err := this.repos(ctx)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
// Compare this list of repositories to our existing one
|
|
// If the repository is new, or if it's update-time has changed since we last
|
|
// saw it, then re-refresh its real git commit timestamps
|
|
// Otherwise copy them from the previous version
|
|
|
|
this.reposMut.RLock() // readonly
|
|
|
|
anyChanges := false
|
|
if len(repos) != len(this.reposCache) {
|
|
anyChanges = true
|
|
}
|
|
|
|
for i, rr := range repos {
|
|
if idx, ok := this.reposAlphabeticalOrder[rr.Name]; ok && this.reposCache[idx].GiteaUpdated == rr.GiteaUpdated {
|
|
// Already exists in cache with same Gitea update time
|
|
// Copy timestamps
|
|
repos[i] = this.reposCache[idx]
|
|
|
|
} else {
|
|
|
|
// New repo, or Gitea has updated timestamp
|
|
anyChanges = true
|
|
|
|
// Refresh timestamps
|
|
this.populateCommitInfo(ctx, &rr)
|
|
|
|
// Refresh topics
|
|
if t, err := this.topicsForRepo(ctx, rr.Name); err == nil {
|
|
rr.topics = t
|
|
}
|
|
|
|
// Save
|
|
repos[i] = rr
|
|
}
|
|
}
|
|
|
|
this.reposMut.RUnlock()
|
|
|
|
//
|
|
if !anyChanges {
|
|
return false, nil // nothing to do
|
|
}
|
|
|
|
// We have a final updated repos array
|
|
|
|
// Sort repos once alphabetically, to get alphabetical indexes...
|
|
sort.Slice(repos, func(i, j int) bool {
|
|
return repos[i].Name < repos[j].Name
|
|
})
|
|
alphabeticalOrderIndexes := make(map[string]int, len(repos))
|
|
for idx, repo := range repos {
|
|
alphabeticalOrderIndexes[repo.Name] = idx
|
|
}
|
|
|
|
// But then make sure the final sort is by most-recently-created
|
|
sort.Slice(repos, func(i, j int) bool {
|
|
return repos[i].GiteaCreated.After(repos[j].GiteaCreated)
|
|
})
|
|
|
|
// Commit our changes for the other threads to look at
|
|
this.reposMut.Lock()
|
|
this.reposCache = repos
|
|
this.reposAlphabeticalOrder = alphabeticalOrderIndexes
|
|
this.reposMut.Unlock()
|
|
|
|
// Done
|
|
return true, nil
|
|
}
|
|
|
|
func (this *Application) syncWorker(ctx context.Context) {
|
|
|
|
t := time.NewTicker(30 * time.Minute)
|
|
defer t.Stop()
|
|
|
|
for {
|
|
anyChanges, err := this.sync(ctx)
|
|
if err != nil {
|
|
// log and continue
|
|
log.Printf("Refreshing repositories: %s", err.Error())
|
|
}
|
|
if anyChanges {
|
|
log.Printf("Repositories updated")
|
|
}
|
|
|
|
select {
|
|
case <-t.C:
|
|
continue
|
|
|
|
case <-ctx.Done():
|
|
return
|
|
}
|
|
}
|
|
}
|