// ALR - Any Linux Repository // Copyright (C) 2025 Евгений Храмов // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . package appbuilder import ( "context" "errors" "log/slog" "github.com/leonelquinteros/gotext" "github.com/urfave/cli/v2" "gitea.plemya-x.ru/Plemya-x/ALR/internal/config" "gitea.plemya-x.ru/Plemya-x/ALR/internal/db" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/repos" ) type AppDeps struct { Cfg *config.ALRConfig DB *db.Database Repos *repos.Repos } func (d *AppDeps) Defer() { if d.DB != nil { if err := d.DB.Close(); err != nil { slog.Warn("failed to close db", "err", err) } } } type AppBuilder struct { deps AppDeps err error ctx context.Context } func New(ctx context.Context) *AppBuilder { return &AppBuilder{ctx: ctx} } func (b *AppBuilder) WithConfig() *AppBuilder { if b.err != nil { return b } cfg := config.New() if err := cfg.Load(); err != nil { slog.Error(gotext.Get("Error loading config"), "err", err) b.err = cli.Exit("", 1) return b } b.deps.Cfg = cfg return b } func (b *AppBuilder) WithDB() *AppBuilder { if b.err != nil { return b } cfg := b.deps.Cfg if cfg == nil { b.err = errors.New("config is required before initializing DB") return b } db := db.New(cfg) if err := db.Init(b.ctx); err != nil { slog.Error(gotext.Get("Error initialization database"), "err", err) b.err = cli.Exit("", 1) return b } b.deps.DB = db return b } func (b *AppBuilder) WithRepos() *AppBuilder { b.withRepos(false) return b } func (b *AppBuilder) WithReposForcePull() *AppBuilder { b.withRepos(true) return b } func (b *AppBuilder) withRepos(forcePull bool) *AppBuilder { if b.err != nil { return b } cfg := b.deps.Cfg db := b.deps.DB if cfg == nil || db == nil { b.err = errors.New("config and db are required before initializing repos") return b } rs := repos.New(cfg, db) if forcePull || cfg.AutoPull() { if err := rs.Pull(b.ctx, cfg.Repos()); err != nil { slog.Error(gotext.Get("Error pulling repositories"), "err", err) b.err = cli.Exit("", 1) return b } } b.deps.Repos = rs return b } func (b *AppBuilder) Build() (*AppDeps, error) { if b.err != nil { return nil, b.err } return &b.deps, nil }