wip
This commit is contained in:
@@ -34,26 +34,10 @@ func New(prs []project.Project) (*Scheduler, error) {
|
||||
func (s *Scheduler) Add(pr project.Project) error {
|
||||
s.ids[pr.Name] = make(map[string]cron.EntryID)
|
||||
for _, repo := range pr.Repositories {
|
||||
var srcAuth git.Authentication = git.NoAuthentication{}
|
||||
var dstAuth git.Authentication = git.NoAuthentication{}
|
||||
if v, ok := repo.Authentications["source"]; ok {
|
||||
if len(v.Token) > 0 {
|
||||
srcAuth = git.NewTokenAuthentication(v.Token)
|
||||
} else if v.Basic != nil {
|
||||
srcAuth = git.NewBasicAuthentication(v.Basic.Username, v.Basic.Password)
|
||||
}
|
||||
}
|
||||
if v, ok := repo.Authentications["mirror"]; ok {
|
||||
if len(v.Token) > 0 {
|
||||
dstAuth = git.NewTokenAuthentication(v.Token)
|
||||
} else if v.Basic != nil {
|
||||
dstAuth = git.NewBasicAuthentication(v.Basic.Username, v.Basic.Password)
|
||||
}
|
||||
}
|
||||
r := git.NewRepository(repo.Source, repo.Destination, srcAuth, dstAuth)
|
||||
gr := s.prepare(repo)
|
||||
id, err := s.cr.AddFunc(repo.Schedule, func() {
|
||||
slog.Info(fmt.Sprintf("[%s] starting sync...", repo.Name))
|
||||
if err := git.Sync(r); err != nil {
|
||||
if err := git.Sync(gr); err != nil {
|
||||
slog.Error(fmt.Sprintf("[%s] failed to sync repository: %s", repo.Name, err))
|
||||
return
|
||||
}
|
||||
@@ -80,6 +64,39 @@ func (s *Scheduler) Remove(pr project.Project) {
|
||||
delete(s.ids, pr.Name)
|
||||
}
|
||||
|
||||
func (s *Scheduler) RunOnce(pr project.Project) error {
|
||||
for _, repo := range pr.Repositories {
|
||||
gr := s.prepare(repo)
|
||||
slog.Info(fmt.Sprintf("[%s] starting sync...", repo.Name))
|
||||
if err := git.Sync(gr); err != nil {
|
||||
slog.Error(fmt.Sprintf("[%s] failed to sync repository: %s", repo.Name, err))
|
||||
continue
|
||||
}
|
||||
slog.Info(fmt.Sprintf("[%s] synced", repo.Name))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Scheduler) prepare(repo project.Repository) git.Repository {
|
||||
var srcAuth git.Authentication = git.NoAuthentication{}
|
||||
var dstAuth git.Authentication = git.NoAuthentication{}
|
||||
if v, ok := repo.Authentications["source"]; ok {
|
||||
if len(v.Token) > 0 {
|
||||
srcAuth = git.NewTokenAuthentication(v.Token)
|
||||
} else if v.Basic != nil {
|
||||
srcAuth = git.NewBasicAuthentication(v.Basic.Username, v.Basic.Password)
|
||||
}
|
||||
}
|
||||
if v, ok := repo.Authentications["mirror"]; ok {
|
||||
if len(v.Token) > 0 {
|
||||
dstAuth = git.NewTokenAuthentication(v.Token)
|
||||
} else if v.Basic != nil {
|
||||
dstAuth = git.NewBasicAuthentication(v.Basic.Username, v.Basic.Password)
|
||||
}
|
||||
}
|
||||
return git.NewRepository(repo.Source, repo.Destination, srcAuth, dstAuth)
|
||||
}
|
||||
|
||||
// Run the cron scheduler, or no-op if already running.
|
||||
func (s *Scheduler) Run() {
|
||||
s.cr.Run()
|
||||
|
||||
@@ -279,6 +279,43 @@ func (r *Repository) updateRepository(tx *sql.Tx, repo project.Repository) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Repository) Remove(pr project.Project) error {
|
||||
tx, err := r.db.Begin()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create transaction: %s", err)
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return
|
||||
}
|
||||
tx.Commit()
|
||||
}()
|
||||
|
||||
uuid, err := r.ProjectUUID(pr.Name)
|
||||
|
||||
repos, err := r.listRepositories(uuid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, repo := range repos {
|
||||
if _, err := tx.Exec("DELETE FROM Authentication WHERE repository = ?", repo.UUID); err != nil {
|
||||
return fmt.Errorf("failed to delete the authentication entries from the database: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := tx.Exec("DELETE FROM Repositories WHERE project = ?", uuid); err != nil {
|
||||
return fmt.Errorf("failed to delete the repositories from the database: %s", err)
|
||||
}
|
||||
|
||||
if _, err := tx.Exec("DELETE FROM Projects WHERE uuid = ?", uuid); err != nil {
|
||||
return fmt.Errorf("failed to delete the project from the database: %s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Repository) List() ([]project.Project, error) {
|
||||
var prs []project.Project
|
||||
|
||||
@@ -288,72 +325,88 @@ func (r *Repository) List() ([]project.Project, error) {
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
stmt, err := r.db.Prepare("SELECT uuid, name, schedule, source, destination FROM Repositories WHERE project = ?")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid syntax: %w", err)
|
||||
}
|
||||
|
||||
authStmt, err := r.db.Prepare("SELECT ref, username, password, token FROM Authentication WHERE repository = ?")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid syntax: %w", err)
|
||||
}
|
||||
for rows.Next() {
|
||||
var pr project.Project
|
||||
var prUUID string
|
||||
if err := rows.Scan(&prUUID, &pr.Name); err != nil {
|
||||
if err := rows.Scan(&pr.UUID, &pr.Name); err != nil {
|
||||
return nil, fmt.Errorf("failed to scan project name: %w", err)
|
||||
}
|
||||
|
||||
repoRows, err := stmt.Query(prUUID)
|
||||
repos, err := r.listRepositories(pr.UUID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to query repositories for the project %s: %w", prUUID, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for repoRows.Next() {
|
||||
var uuid string
|
||||
var repo project.Repository
|
||||
if err := repoRows.Scan(&uuid, &repo.Name, &repo.Schedule, &repo.Source, &repo.Destination); err != nil {
|
||||
repoRows.Close()
|
||||
return nil, fmt.Errorf("failed to scan repository entry: %w", err)
|
||||
}
|
||||
pr.Repositories = repos
|
||||
|
||||
authRows, err := authStmt.Query(uuid)
|
||||
if err != nil {
|
||||
repoRows.Close()
|
||||
return nil, fmt.Errorf("failed to query repositories for the project %s: %w", prUUID, err)
|
||||
}
|
||||
|
||||
auth := make(map[string]project.AuthenticationSettings)
|
||||
for authRows.Next() {
|
||||
var ref string
|
||||
var username, password, token *string
|
||||
if err := authRows.Scan(&ref, &username, &password, &token); err != nil {
|
||||
authRows.Close()
|
||||
repoRows.Close()
|
||||
return nil, fmt.Errorf("failed to scan authentication entry: %s", err)
|
||||
}
|
||||
if token != nil {
|
||||
auth[ref] = project.AuthenticationSettings{
|
||||
Token: *token,
|
||||
}
|
||||
} else if username != nil {
|
||||
auth[ref] = project.AuthenticationSettings{
|
||||
Basic: &project.BasicAuthenticationSettings{
|
||||
Username: *username,
|
||||
Password: *password,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
authRows.Close()
|
||||
repo.Authentications = auth
|
||||
pr.Repositories = append(pr.Repositories, repo)
|
||||
}
|
||||
|
||||
repoRows.Close()
|
||||
prs = append(prs, pr)
|
||||
}
|
||||
|
||||
return prs, nil
|
||||
}
|
||||
|
||||
func (r *Repository) listRepositories(projectUUID string) ([]project.Repository, error) {
|
||||
stmt, err := r.db.Prepare("SELECT uuid, name, schedule, source, destination FROM Repositories WHERE project = ?")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid syntax: %w", err)
|
||||
}
|
||||
|
||||
rows, err := stmt.Query(projectUUID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to query repositories for the project %s: %w", projectUUID, err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var repositories []project.Repository
|
||||
for rows.Next() {
|
||||
var repo project.Repository
|
||||
if err := rows.Scan(&repo.UUID, &repo.Name, &repo.Schedule, &repo.Source, &repo.Destination); err != nil {
|
||||
return nil, fmt.Errorf("failed to scan repository entry: %w", err)
|
||||
}
|
||||
|
||||
auth, err := r.listAuthentications(repo.UUID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
repo.Authentications = auth
|
||||
|
||||
repositories = append(repositories, repo)
|
||||
}
|
||||
|
||||
return repositories, nil
|
||||
}
|
||||
|
||||
func (r *Repository) listAuthentications(repositoryUUID string) (map[string]project.AuthenticationSettings, error) {
|
||||
stmt, err := r.db.Prepare("SELECT ref, username, password, token FROM Authentication WHERE repository = ?")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid syntax: %w", err)
|
||||
}
|
||||
|
||||
rows, err := stmt.Query(repositoryUUID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to query repositories for the project %s: %w", repositoryUUID, err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
res := make(map[string]project.AuthenticationSettings)
|
||||
for rows.Next() {
|
||||
var ref string
|
||||
var username, password, token *string
|
||||
if err := rows.Scan(&ref, &username, &password, &token); err != nil {
|
||||
return nil, fmt.Errorf("failed to scan authentication entry: %s", err)
|
||||
}
|
||||
if token != nil {
|
||||
res[ref] = project.AuthenticationSettings{
|
||||
Token: *token,
|
||||
}
|
||||
} else if username != nil {
|
||||
res[ref] = project.AuthenticationSettings{
|
||||
Basic: &project.BasicAuthenticationSettings{
|
||||
Username: *username,
|
||||
Password: *password,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user