fix (wip)

This commit is contained in:
2025-10-26 22:35:52 +01:00
parent 6224e63fa9
commit 9406ffda01
7 changed files with 52 additions and 19 deletions

View File

@@ -87,7 +87,7 @@ func unauthorized(w http.ResponseWriter, r *http.Request) {
} }
func ok(o interface{}, w http.ResponseWriter, r *http.Request) { func ok(o interface{}, w http.ResponseWriter, r *http.Request) {
payload := obj.HTTPObject{ payload := obj.HTTPObject[any]{
HTTPCore: obj.HTTPCore{ HTTPCore: obj.HTTPCore{
Status: http.StatusOK, Status: http.StatusOK,
Path: r.RequestURI, Path: r.RequestURI,

View File

@@ -227,13 +227,13 @@ func (r *Repository) Update(pr project.Project) error {
func (r *Repository) List() ([]project.Project, error) { func (r *Repository) List() ([]project.Project, error) {
var prs []project.Project var prs []project.Project
rows, err := r.db.Query("SELECT uuid, name WHERE Projects") rows, err := r.db.Query("SELECT uuid, name FROM Projects")
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to get the list of projects: %w", err) return nil, fmt.Errorf("failed to get the list of projects: %w", err)
} }
defer rows.Close() defer rows.Close()
stmt, err := r.db.Prepare("SELECT name, schedule, source, destination FROM Repositories WHERE uuid = ?") stmt, err := r.db.Prepare("SELECT name, schedule, source, destination FROM Repositories WHERE project = ?")
if err != nil { if err != nil {
return nil, fmt.Errorf("invalid syntax: %w", err) return nil, fmt.Errorf("invalid syntax: %w", err)
} }
@@ -244,18 +244,21 @@ func (r *Repository) List() ([]project.Project, error) {
return nil, fmt.Errorf("failed to scan project name: %w", err) return nil, fmt.Errorf("failed to scan project name: %w", err)
} }
for rows.Next() { repoRows, err := stmt.Query(prUUID)
if err != nil {
return nil, fmt.Errorf("failed to query repositories for the project %s: %w", prUUID, err)
}
for repoRows.Next() {
var repo project.Repository var repo project.Repository
rows, err := stmt.Query(prUUID) if err := repoRows.Scan(&repo.Name, &repo.Schedule, &repo.Source, &repo.Destination); err != nil {
if err != nil { repoRows.Close()
return nil, fmt.Errorf("failed to get the list of projects: %w", err)
}
if err := rows.Scan(&repo.Name, &repo.Schedule, &repo.Source, &repo.Destination); err != nil {
return nil, fmt.Errorf("failed to scan repository entry: %w", err) return nil, fmt.Errorf("failed to scan repository entry: %w", err)
} }
pr.Repositories = append(pr.Repositories, repo) pr.Repositories = append(pr.Repositories, repo)
} }
repoRows.Close()
prs = append(prs, pr) prs = append(prs, pr)
} }

1
go.mod
View File

@@ -10,6 +10,7 @@ require (
github.com/google/subcommands v1.2.0 github.com/google/subcommands v1.2.0
github.com/google/uuid v1.6.0 github.com/google/uuid v1.6.0
github.com/pressly/goose/v3 v3.26.0 github.com/pressly/goose/v3 v3.26.0
github.com/robfig/cron/v3 v3.0.1
) )
require ( require (

2
go.sum
View File

@@ -64,6 +64,8 @@ github.com/pressly/goose/v3 v3.26.0 h1:KJakav68jdH0WDvoAcj8+n61WqOIaPGgH0bJWS6jp
github.com/pressly/goose/v3 v3.26.0/go.mod h1:4hC1KrritdCxtuFsqgs1R4AU5bWtTAf+cnWvfhf2DNY= github.com/pressly/goose/v3 v3.26.0/go.mod h1:4hC1KrritdCxtuFsqgs1R4AU5bWtTAf+cnWvfhf2DNY=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw=
github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
github.com/sethvargo/go-retry v0.3.0 h1:EEt31A35QhrcRZtrYFDTBg91cqZVnFL2navjDrah2SE= github.com/sethvargo/go-retry v0.3.0 h1:EEt31A35QhrcRZtrYFDTBg91cqZVnFL2navjDrah2SE=

View File

@@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"io" "io"
"mirror-sync/pkg/project" "mirror-sync/pkg/project"
"mirror-sync/pkg/remote/obj"
"net/http" "net/http"
"net/url" "net/url"
) )
@@ -71,16 +72,18 @@ func (c *Client) List() ([]project.Project, error) {
} }
defer res.Body.Close() defer res.Body.Close()
if res.StatusCode != 201 { if res.StatusCode != 200 {
return nil, fmt.Errorf("failed to send the request to the server: %s: %s", res.Status, toError(res.Body)) return nil, fmt.Errorf("failed to send the request to the server: %s: %s", res.Status, toError(res.Body))
} }
var prs []project.Project var payload obj.HTTPObject[[]project.Project]
d := json.NewDecoder(res.Body) d := json.NewDecoder(res.Body)
if err := d.Decode(&prs); err != nil { if err := d.Decode(&payload); err != nil {
return nil, fmt.Errorf("failed to parse the server response, is the client you up-to-date? (reason: %s)", err) return nil, fmt.Errorf("failed to parse the server response, is your client up-to-date? (reason: %s)", err)
} }
prs := payload.Data
for i, pr := range prs { for i, pr := range prs {
pr.ServerURL = c.url pr.ServerURL = c.url
prs[i] = pr prs[i] = pr

View File

@@ -8,6 +8,7 @@ import (
"strings" "strings"
"github.com/goccy/go-yaml" "github.com/goccy/go-yaml"
"github.com/robfig/cron/v3"
) )
type ( type (
@@ -29,8 +30,8 @@ type (
} }
GitStorage struct { GitStorage struct {
Source string `yaml:"source"` Source string `yaml:"source"`
Destination string `yaml:"destination"` Mirror string `yaml:"mirror"`
} }
) )
@@ -58,6 +59,10 @@ func LoadCurrent() (Project, error) {
return Project{}, fmt.Errorf("%w: %s", ErrParsing, err) return Project{}, fmt.Errorf("%w: %s", ErrParsing, err)
} }
if err := checkConfig(mainFile); err != nil {
return Project{}, fmt.Errorf("failed to validate configuration: %w", err)
}
pr := Project{ pr := Project{
Name: filepath.Base(wd), Name: filepath.Base(wd),
ServerURL: "http://localhost:8080", ServerURL: "http://localhost:8080",
@@ -83,10 +88,29 @@ func LoadCurrent() (Project, error) {
pr.Repositories = append(pr.Repositories, Repository{ pr.Repositories = append(pr.Repositories, Repository{
Name: fmt.Sprintf("%s-%s", pr.Name, strings.ToLower(repoName)), Name: fmt.Sprintf("%s-%s", pr.Name, strings.ToLower(repoName)),
Source: repo.Storage.Source, Source: repo.Storage.Source,
Destination: repo.Storage.Destination, Destination: repo.Storage.Mirror,
Schedule: repo.Schedule, Schedule: repo.Schedule,
}) })
} }
return pr, nil return pr, nil
} }
func checkConfig(mf MainFile) error {
for _, r := range mf.Repositories {
if len(strings.TrimSpace(r.Storage.Source)) == 0 {
return fmt.Errorf("source is empty")
}
if len(strings.TrimSpace(r.Storage.Mirror)) == 0 {
return fmt.Errorf("mirror is empty")
}
if len(strings.TrimSpace(r.Schedule)) == 0 {
return fmt.Errorf("schedule is empty")
}
if _, err := cron.ParseStandard(r.Schedule); err != nil {
return fmt.Errorf("failed to validate schedule: %w", err)
}
}
return nil
}

View File

@@ -15,9 +15,9 @@ type (
Message string `json:"message"` Message string `json:"message"`
} }
HTTPObject struct { HTTPObject[T any] struct {
HTTPCore HTTPCore
Data any `json:"data"` Data T `json:"data"`
} }
SystemInformation struct { SystemInformation struct {