diff --git a/build.go b/build.go
index 2c63799..a033182 100644
--- a/build.go
+++ b/build.go
@@ -117,7 +117,7 @@ func BuildCmd() *cli.Command {
os.Exit(1)
}
- builder := build.New(
+ builder := build.NewBuilder(
ctx,
types.BuildOpts{
Package: packageName,
diff --git a/coverage-badge.svg b/coverage-badge.svg
index b7b7768..b686468 100644
--- a/coverage-badge.svg
+++ b/coverage-badge.svg
@@ -11,7 +11,7 @@
coverage
coverage
- 19.7%
- 19.7%
+ 20.8%
+ 20.8%
diff --git a/install.go b/install.go
index 54982b4..2706ada 100644
--- a/install.go
+++ b/install.go
@@ -29,9 +29,10 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
- "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
+ database "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/build"
+ "gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/manager"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/repos"
)
@@ -63,22 +64,52 @@ func InstallCmd() *cli.Command {
os.Exit(1)
}
- if config.GetInstance(ctx).AutoPull(ctx) {
- err := repos.Pull(ctx, config.Config(ctx).Repos)
+ cfg := config.New()
+ db := database.New(cfg)
+ rs := repos.New(cfg, db)
+ err := db.Init(ctx)
+ if err != nil {
+ slog.Error(gotext.Get("Error db init"), "err", err)
+ os.Exit(1)
+ }
+
+ if cfg.AutoPull(ctx) {
+ err := rs.Pull(ctx, cfg.Repos(ctx))
if err != nil {
slog.Error(gotext.Get("Error pulling repositories"), "err", err)
os.Exit(1)
}
}
- found, notFound, err := repos.FindPkgs(ctx, args.Slice())
+ found, notFound, err := rs.FindPkgs(ctx, args.Slice())
if err != nil {
slog.Error(gotext.Get("Error finding packages"), "err", err)
os.Exit(1)
}
pkgs := cliutils.FlattenPkgs(ctx, found, "install", c.Bool("interactive"))
- build.InstallPkgs(ctx, pkgs, notFound, types.BuildOpts{
+
+ opts := types.BuildOpts{
+ Manager: mgr,
+ Clean: c.Bool("clean"),
+ Interactive: c.Bool("interactive"),
+ }
+
+ info, err := distro.ParseOSRelease(ctx)
+ if err != nil {
+ slog.Error(gotext.Get("Error parsing os release"), "err", err)
+ os.Exit(1)
+ }
+
+ builder := build.NewBuilder(
+ ctx,
+ opts,
+ rs,
+ info,
+ cfg,
+ )
+
+ builder.InstallPkgs(ctx, pkgs, notFound, types.BuildOpts{
Manager: mgr,
Clean: c.Bool("clean"),
Interactive: c.Bool("interactive"),
@@ -86,6 +117,8 @@ func InstallCmd() *cli.Command {
return nil
},
BashComplete: func(c *cli.Context) {
+ cfg := config.New()
+ db := database.New(cfg)
result, err := db.GetPkgs(c.Context, "true")
if err != nil {
slog.Error(gotext.Get("Error getting packages"), "err", err)
@@ -94,7 +127,7 @@ func InstallCmd() *cli.Command {
defer result.Close()
for result.Next() {
- var pkg db.Package
+ var pkg database.Package
err = result.StructScan(&pkg)
if err != nil {
slog.Error(gotext.Get("Error iterating over packages"), "err", err)
diff --git a/internal/translations/default.pot b/internal/translations/default.pot
index f2e3d0a..9b9b614 100644
--- a/internal/translations/default.pot
+++ b/internal/translations/default.pot
@@ -138,31 +138,31 @@ msgstr ""
msgid "Error encoding script variables"
msgstr ""
-#: install.go:42
+#: install.go:43
msgid "Install a new package"
msgstr ""
-#: install.go:56
+#: install.go:57
msgid "Command install expected at least 1 argument, got %d"
msgstr ""
-#: install.go:91
+#: install.go:124
msgid "Error getting packages"
msgstr ""
-#: install.go:100
+#: install.go:133
msgid "Error iterating over packages"
msgstr ""
-#: install.go:113
+#: install.go:146
msgid "Remove an installed package"
msgstr ""
-#: install.go:118
+#: install.go:151
msgid "Command remove expected at least 1 argument, got %d"
msgstr ""
-#: install.go:130
+#: install.go:163
msgid "Error removing packages"
msgstr ""
@@ -301,78 +301,78 @@ msgstr ""
msgid "Error while running app"
msgstr ""
-#: pkg/build/build.go:116
+#: pkg/build/build.go:135
msgid "Failed to prompt user to view build script"
msgstr ""
-#: pkg/build/build.go:120
+#: pkg/build/build.go:139
msgid "Building package"
msgstr ""
-#: pkg/build/build.go:164
+#: pkg/build/build.go:183
msgid "Downloading sources"
msgstr ""
-#: pkg/build/build.go:176
+#: pkg/build/build.go:195
msgid "Building package metadata"
msgstr ""
-#: pkg/build/build.go:198
+#: pkg/build/build.go:217
msgid "Compressing package"
msgstr ""
-#: pkg/build/build.go:322
+#: pkg/build/build.go:341
msgid ""
"Your system's CPU architecture doesn't match this package. Do you want to "
"build anyway?"
msgstr ""
-#: pkg/build/build.go:336
+#: pkg/build/build.go:355
msgid "This package is already installed"
msgstr ""
-#: pkg/build/build.go:360
+#: pkg/build/build.go:379
msgid "Installing build dependencies"
msgstr ""
-#: pkg/build/build.go:371
+#: pkg/build/build.go:390
msgid "Installing dependencies"
msgstr ""
-#: pkg/build/build.go:419
+#: pkg/build/build.go:431
msgid "The checksums array must be the same length as sources"
msgstr ""
-#: pkg/build/build.go:470
+#: pkg/build/build.go:482
msgid "Would you like to remove the build dependencies?"
msgstr ""
-#: pkg/build/build.go:507
+#: pkg/build/build.go:519
msgid "Executing version()"
msgstr ""
-#: pkg/build/build.go:527
+#: pkg/build/build.go:539
msgid "Updating version"
msgstr ""
-#: pkg/build/build.go:532
+#: pkg/build/build.go:544
msgid "Executing prepare()"
msgstr ""
-#: pkg/build/build.go:542
+#: pkg/build/build.go:554
msgid "Executing build()"
msgstr ""
-#: pkg/build/build.go:558 pkg/build/build.go:586
+#: pkg/build/build.go:570 pkg/build/build.go:598
msgid "Executing %s()"
msgstr ""
-#: pkg/build/build_legacy.go:196
-msgid "AutoProv is not implemented for this package format, so it's skipped"
+#: pkg/build/build.go:657
+msgid "Error installing native packages"
msgstr ""
-#: pkg/build/build_legacy.go:207
-msgid "AutoReq is not implemented for this package format, so it's skipped"
+#: pkg/build/build.go:683
+msgid "Error installing package"
msgstr ""
#: pkg/build/findDeps.go:35
@@ -387,12 +387,12 @@ msgstr ""
msgid "Required dependency found"
msgstr ""
-#: pkg/build/install.go:44
-msgid "Error installing native packages"
+#: pkg/build/utils.go:136
+msgid "AutoProv is not implemented for this package format, so it's skipped"
msgstr ""
-#: pkg/build/install.go:94
-msgid "Error installing package"
+#: pkg/build/utils.go:147
+msgid "AutoReq is not implemented for this package format, so it's skipped"
msgstr ""
#: pkg/repos/pull.go:79
@@ -461,10 +461,10 @@ msgstr ""
msgid "Upgrade all installed packages"
msgstr ""
-#: upgrade.go:83
+#: upgrade.go:90
msgid "Error checking for updates"
msgstr ""
-#: upgrade.go:94
+#: upgrade.go:112
msgid "There is nothing to do."
msgstr ""
diff --git a/internal/translations/po/ru/default.po b/internal/translations/po/ru/default.po
index de06d3b..c31e583 100644
--- a/internal/translations/po/ru/default.po
+++ b/internal/translations/po/ru/default.po
@@ -146,31 +146,31 @@ msgstr "Ошибка устранения переорпеделений"
msgid "Error encoding script variables"
msgstr "Ошибка кодирования переменных скрита"
-#: install.go:42
+#: install.go:43
msgid "Install a new package"
msgstr "Установить новый пакет"
-#: install.go:56
+#: install.go:57
msgid "Command install expected at least 1 argument, got %d"
msgstr "Для команды install ожидался хотя бы 1 аргумент, получено %d"
-#: install.go:91
+#: install.go:124
msgid "Error getting packages"
msgstr "Ошибка при получении пакетов"
-#: install.go:100
+#: install.go:133
msgid "Error iterating over packages"
msgstr "Ошибка при переборе пакетов"
-#: install.go:113
+#: install.go:146
msgid "Remove an installed package"
msgstr "Удалить установленный пакет"
-#: install.go:118
+#: install.go:151
msgid "Command remove expected at least 1 argument, got %d"
msgstr "Для команды remove ожидался хотя бы 1 аргумент, получено %d"
-#: install.go:130
+#: install.go:163
msgid "Error removing packages"
msgstr "Ошибка при удалении пакетов"
@@ -316,27 +316,27 @@ msgstr ""
msgid "Error while running app"
msgstr "Ошибка при запуске приложения"
-#: pkg/build/build.go:116
+#: pkg/build/build.go:135
msgid "Failed to prompt user to view build script"
msgstr "Не удалось предложить пользователю просмотреть скрипт сборки"
-#: pkg/build/build.go:120
+#: pkg/build/build.go:139
msgid "Building package"
msgstr "Сборка пакета"
-#: pkg/build/build.go:164
+#: pkg/build/build.go:183
msgid "Downloading sources"
msgstr "Скачивание источников"
-#: pkg/build/build.go:176
+#: pkg/build/build.go:195
msgid "Building package metadata"
msgstr "Сборка метаданных пакета"
-#: pkg/build/build.go:198
+#: pkg/build/build.go:217
msgid "Compressing package"
msgstr "Сжатие пакета"
-#: pkg/build/build.go:322
+#: pkg/build/build.go:341
msgid ""
"Your system's CPU architecture doesn't match this package. Do you want to "
"build anyway?"
@@ -344,56 +344,54 @@ msgstr ""
"Архитектура процессора вашей системы не соответствует этому пакету. Вы все "
"равно хотите выполнить сборку?"
-#: pkg/build/build.go:336
+#: pkg/build/build.go:355
msgid "This package is already installed"
msgstr "Этот пакет уже установлен"
-#: pkg/build/build.go:360
+#: pkg/build/build.go:379
msgid "Installing build dependencies"
msgstr "Установка зависимостей сборки"
-#: pkg/build/build.go:371
+#: pkg/build/build.go:390
msgid "Installing dependencies"
msgstr "Установка зависимостей"
-#: pkg/build/build.go:419
+#: pkg/build/build.go:431
msgid "The checksums array must be the same length as sources"
msgstr "Массив контрольных сумм должен быть той же длины, что и источники"
-#: pkg/build/build.go:470
+#: pkg/build/build.go:482
msgid "Would you like to remove the build dependencies?"
msgstr "Хотели бы вы удалить зависимости сборки?"
-#: pkg/build/build.go:507
+#: pkg/build/build.go:519
msgid "Executing version()"
msgstr "Исполнение версия()"
-#: pkg/build/build.go:527
+#: pkg/build/build.go:539
msgid "Updating version"
msgstr "Обновление версии"
-#: pkg/build/build.go:532
+#: pkg/build/build.go:544
msgid "Executing prepare()"
msgstr "Исполнение prepare()"
-#: pkg/build/build.go:542
+#: pkg/build/build.go:554
msgid "Executing build()"
msgstr "Исполнение build()"
-#: pkg/build/build.go:558 pkg/build/build.go:586
+#: pkg/build/build.go:570 pkg/build/build.go:598
#, fuzzy
msgid "Executing %s()"
msgstr "Исполнение files()"
-#: pkg/build/build_legacy.go:196
-msgid "AutoProv is not implemented for this package format, so it's skipped"
-msgstr ""
-"AutoProv не реализовано для этого формата пакета, поэтому будет пропущено"
+#: pkg/build/build.go:657
+msgid "Error installing native packages"
+msgstr "Ошибка при установке нативных пакетов"
-#: pkg/build/build_legacy.go:207
-msgid "AutoReq is not implemented for this package format, so it's skipped"
-msgstr ""
-"AutoReq не реализовано для этого формата пакета, поэтому будет пропущено"
+#: pkg/build/build.go:683
+msgid "Error installing package"
+msgstr "Ошибка при установке пакета"
#: pkg/build/findDeps.go:35
msgid "Command not found on the system"
@@ -407,13 +405,15 @@ msgstr "Найденная предоставленная зависимость
msgid "Required dependency found"
msgstr "Найдена требуемая зависимость"
-#: pkg/build/install.go:44
-msgid "Error installing native packages"
-msgstr "Ошибка при установке нативных пакетов"
+#: pkg/build/utils.go:136
+msgid "AutoProv is not implemented for this package format, so it's skipped"
+msgstr ""
+"AutoProv не реализовано для этого формата пакета, поэтому будет пропущено"
-#: pkg/build/install.go:94
-msgid "Error installing package"
-msgstr "Ошибка при установке пакета"
+#: pkg/build/utils.go:147
+msgid "AutoReq is not implemented for this package format, so it's skipped"
+msgstr ""
+"AutoReq не реализовано для этого формата пакета, поэтому будет пропущено"
#: pkg/repos/pull.go:79
msgid "Pulling repository"
@@ -483,11 +483,11 @@ msgstr "Скачать все изменённые репозитории"
msgid "Upgrade all installed packages"
msgstr "Обновить все установленные пакеты"
-#: upgrade.go:83
+#: upgrade.go:90
msgid "Error checking for updates"
msgstr "Ошибка при проверке обновлений"
-#: upgrade.go:94
+#: upgrade.go:112
msgid "There is nothing to do."
msgstr "Здесь нечего делать."
diff --git a/pkg/build/build.go b/pkg/build/build.go
index 9125530..56cd4b0 100644
--- a/pkg/build/build.go
+++ b/pkg/build/build.go
@@ -41,6 +41,7 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cpu"
+ "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/dl"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/dlcache"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/decoder"
@@ -49,23 +50,31 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/manager"
- "gitea.plemya-x.ru/Plemya-x/ALR/pkg/repos"
)
+type PackageFinder interface {
+ FindPkgs(ctx context.Context, pkgs []string) (map[string][]db.Package, []string, error)
+}
+
+type Config interface {
+ GetPaths(ctx context.Context) *config.Paths
+ PagerStyle(ctx context.Context) string
+}
+
type Builder struct {
ctx context.Context
opts types.BuildOpts
info *distro.OSRelease
- repos *repos.Repos
- config *config.ALRConfig
+ repos PackageFinder
+ config Config
}
-func New(
+func NewBuilder(
ctx context.Context,
opts types.BuildOpts,
- repos *repos.Repos,
+ repos PackageFinder,
info *distro.OSRelease,
- config *config.ALRConfig,
+ config Config,
) *Builder {
return &Builder{
ctx: ctx,
@@ -76,6 +85,16 @@ func New(
}
}
+func (b *Builder) UpdateOptsFromPkg(pkg *db.Package) {
+ repodir := b.config.GetPaths(b.ctx).RepoDir
+ if pkg.BasePkgName != "" {
+ b.opts.Script = filepath.Join(repodir, pkg.Repository, pkg.BasePkgName, "alr.sh")
+ b.opts.Package = pkg.Name
+ } else {
+ b.opts.Script = filepath.Join(repodir, pkg.Repository, pkg.Name, "alr.sh")
+ }
+}
+
func (b *Builder) BuildPackage(ctx context.Context) ([]string, []string, error) {
fl, err := readScript(b.opts.Script)
if err != nil {
@@ -151,7 +170,7 @@ func (b *Builder) BuildPackage(ctx context.Context) ([]string, []string, error)
return nil, nil, err
}
- err = installOptDeps(ctx, b.repos, vars, b.opts) // Устанавливаем опциональные зависимости
+ err = b.installOptDeps(ctx, vars) // Устанавливаем опциональные зависимости
if err != nil {
return nil, nil, err
}
@@ -352,7 +371,7 @@ func (b *Builder) installBuildDeps(ctx context.Context, vars *types.BuildVars) (
return nil, err
}
- found, notFound, err := repos.FindPkgs(ctx, deps) // Находим пакеты-зависимости
+ found, notFound, err := b.repos.FindPkgs(ctx, deps) // Находим пакеты-зависимости
if err != nil {
return nil, err
}
@@ -361,7 +380,7 @@ func (b *Builder) installBuildDeps(ctx context.Context, vars *types.BuildVars) (
flattened := cliutils.FlattenPkgs(ctx, found, "install", b.opts.Interactive) // Уплощаем список зависимостей
buildDeps = packageNames(flattened)
- InstallPkgs(ctx, flattened, notFound, b.opts) // Устанавливаем пакеты
+ b.InstallPkgs(ctx, flattened, notFound, b.opts) // Устанавливаем пакеты
}
return buildDeps, nil
}
@@ -370,7 +389,7 @@ func (b *Builder) buildALRDeps(ctx context.Context, vars *types.BuildVars) (buil
if len(vars.Depends) > 0 {
slog.Info(gotext.Get("Installing dependencies"))
- found, notFound, err := repos.FindPkgs(ctx, vars.Depends) // Поиск зависимостей
+ found, notFound, err := b.repos.FindPkgs(ctx, vars.Depends) // Поиск зависимостей
if err != nil {
return nil, nil, nil, err
}
@@ -380,16 +399,9 @@ func (b *Builder) buildALRDeps(ctx context.Context, vars *types.BuildVars) (buil
pkgs := cliutils.FlattenPkgs(ctx, found, "install", b.opts.Interactive)
for _, pkg := range pkgs {
- newOpts := b.opts
- UpdateOpts(ctx, &newOpts, &pkg)
- newB := New(
- ctx,
- newOpts,
- b.repos,
- b.info,
- b.config,
- )
+ newB := *b
+ newB.UpdateOptsFromPkg(&pkg)
// Собираем зависимости
pkgPaths, pkgNames, err := newB.BuildPackage(ctx)
@@ -402,7 +414,7 @@ func (b *Builder) buildALRDeps(ctx context.Context, vars *types.BuildVars) (buil
// Добавляем пути всех собранных пакетов в builtPaths
builtNames = append(builtNames, pkgNames...)
// Добавляем имя текущего пакета в builtNames
- builtNames = append(builtNames, filepath.Base(filepath.Dir(newOpts.Script)))
+ builtNames = append(builtNames, filepath.Base(filepath.Dir(newB.opts.Script)))
}
}
@@ -605,3 +617,72 @@ func (b *Builder) executeFunctions(
return output, nil
}
+
+func (b *Builder) installOptDeps(ctx context.Context, vars *types.BuildVars) error {
+ optDeps, err := removeAlreadyInstalled(b.opts, vars.OptDepends)
+ if err != nil {
+ return err
+ }
+ if len(optDeps) > 0 {
+ optDeps, err := cliutils.ChooseOptDepends(ctx, optDeps, "install", b.opts.Interactive) // Пользователя просят выбрать опциональные зависимости
+ if err != nil {
+ return err
+ }
+
+ if len(optDeps) == 0 {
+ return nil
+ }
+
+ found, notFound, err := b.repos.FindPkgs(ctx, optDeps) // Находим опциональные зависимости
+ if err != nil {
+ return err
+ }
+
+ flattened := cliutils.FlattenPkgs(ctx, found, "install", b.opts.Interactive)
+ b.InstallPkgs(ctx, flattened, notFound, b.opts) // Устанавливаем выбранные пакеты
+ }
+ return nil
+}
+
+func (b *Builder) InstallPkgs(
+ ctx context.Context,
+ alrPkgs []db.Package,
+ nativePkgs []string,
+ opts types.BuildOpts,
+) {
+ if len(nativePkgs) > 0 {
+ err := opts.Manager.Install(nil, nativePkgs...)
+ // Если есть нативные пакеты, выполняем их установку
+ if err != nil {
+ slog.Error(gotext.Get("Error installing native packages"), "err", err)
+ os.Exit(1)
+ // Логируем и завершаем выполнение при ошибке
+ }
+ }
+
+ b.InstallALRPackages(ctx, alrPkgs, opts)
+ // Устанавливаем скрипты сборки через функцию InstallScripts
+}
+
+func (b *Builder) InstallALRPackages(ctx context.Context, pkgs []db.Package, opts types.BuildOpts) {
+ for _, pkg := range pkgs {
+ builder := *b
+ builder.UpdateOptsFromPkg(&pkg)
+
+ builtPkgs, _, err := builder.BuildPackage(ctx)
+ // Выполняем сборку пакета
+ if err != nil {
+ slog.Error(gotext.Get("Error building package"), "err", err)
+ os.Exit(1)
+ // Логируем и завершаем выполнение при ошибке сборки
+ }
+
+ err = opts.Manager.InstallLocal(nil, builtPkgs...)
+ // Устанавливаем локально собранные пакеты
+ if err != nil {
+ slog.Error(gotext.Get("Error installing package"), "err", err)
+ os.Exit(1)
+ // Логируем и завершаем выполнение при ошибке установки
+ }
+ }
+}
diff --git a/pkg/build/build_internal_test.go b/pkg/build/build_internal_test.go
index e09fac0..afffcbd 100644
--- a/pkg/build/build_internal_test.go
+++ b/pkg/build/build_internal_test.go
@@ -18,10 +18,18 @@ package build
import (
"context"
+ "fmt"
+ "os"
+ "strings"
"testing"
+ "github.com/stretchr/testify/assert"
+ "mvdan.cc/sh/v3/syntax"
+
+ "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/internal/types"
+ "gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/manager"
)
@@ -134,93 +142,143 @@ func (m *TestManager) IsInstalled(pkg string) (bool, error) {
return true, nil
}
-// TODO: fix test
-func TestInstallBuildDeps(t *testing.T) {
- type testEnv struct {
- pf PackageFinder
- vars *types.BuildVars
- opts types.BuildOpts
+type TestConfig struct{}
- // Contains pkgs captured by FindPkgsFunc
- // capturedPkgs []string
+func (c *TestConfig) PagerStyle(ctx context.Context) string {
+ return "native"
+}
+
+func (c *TestConfig) GetPaths(ctx context.Context) *config.Paths {
+ return &config.Paths{
+ CacheDir: "/tmp",
+ }
+}
+
+func TestExecuteFirstPassIsSecure(t *testing.T) {
+ cfg := &TestConfig{}
+ pf := &TestPackageFinder{}
+ info := &distro.OSRelease{}
+ m := &TestManager{}
+
+ opts := types.BuildOpts{
+ Manager: m,
+ Interactive: false,
}
+ ctx := context.Background()
+
+ b := NewBuilder(
+ ctx,
+ opts,
+ pf,
+ info,
+ cfg,
+ )
+
+ tmpFile, err := os.CreateTemp("", "testfile-")
+ assert.NoError(t, err)
+ tmpFilePath := tmpFile.Name()
+ defer os.Remove(tmpFilePath)
+
+ _, err = os.Stat(tmpFilePath)
+ assert.NoError(t, err)
+
+ testScript := fmt.Sprintf(`name='test'
+version=1.0.0
+release=1
+rm -f %s`, tmpFilePath)
+
+ fl, err := syntax.NewParser().Parse(strings.NewReader(testScript), "alr.sh")
+ assert.NoError(t, err)
+
+ _, err = b.executeFirstPass(fl)
+ assert.NoError(t, err)
+
+ _, err = os.Stat(tmpFilePath)
+ assert.NoError(t, err)
+}
+
+func TestExecuteFirstPassIsCorrect(t *testing.T) {
type testCase struct {
Name string
- Prepare func() *testEnv
- Expected func(t *testing.T, e *testEnv, res []string, err error)
+ Script string
+ Opts types.BuildOpts
+ Expected func(t *testing.T, vars *types.BuildVars)
}
- for _, tc := range []testCase{
- /*
- {
- Name: "install only needed deps",
- Prepare: func() *testEnv {
- pf := TestPackageFinder{}
- vars := types.BuildVars{}
- m := TestManager{}
- opts := types.BuildOpts{
- Manager: &m,
- Interactive: false,
- }
+ for _, tc := range []testCase{{
+ Name: "single package",
+ Script: `name='test'
+version='1.0.0'
+release=1
+epoch=2
+desc="Test package"
+homepage='https://example.com'
+maintainer='Ivan Ivanov'
+`,
+ Opts: types.BuildOpts{
+ Manager: &TestManager{},
+ Interactive: false,
+ },
+ Expected: func(t *testing.T, vars *types.BuildVars) {
+ assert.Equal(t, vars.Name, "test")
+ assert.Equal(t, vars.Version, "1.0.0")
+ assert.Equal(t, vars.Release, int(1))
+ assert.Equal(t, vars.Epoch, uint(2))
+ assert.Equal(t, vars.Description, "Test package")
+ },
+ }, {
+ Name: "multiple packages",
+ Script: `name=(
+ foo
+ bar
+)
- env := &testEnv{
- pf: &pf,
- vars: &vars,
- opts: opts,
- capturedPkgs: []string{},
- }
+version='0.0.1'
+release=1
+epoch=2
+desc="Test package"
- pf.FindPkgsFunc = func(ctx context.Context, pkgs []string) (map[string][]db.Package, []string, error) {
- env.capturedPkgs = append(env.capturedPkgs, pkgs...)
- result := make(map[string][]db.Package)
- result["bar"] = []db.Package{{
- Name: "bar-pkg",
- }}
- result["buz"] = []db.Package{{
- Name: "buz-pkg",
- }}
+meta_foo() {
+ desc="Foo package"
+}
- return result, []string{}, nil
- }
+meta_bar() {
- vars.BuildDepends = []string{
- "foo",
- "bar",
- "buz",
- }
- m.IsInstalledFunc = func(pkg string) (bool, error) {
- if pkg == "foo" {
- return true, nil
- } else {
- return false, nil
- }
- }
+}
+`,
+ Opts: types.BuildOpts{
+ Package: "foo",
+ Manager: &TestManager{},
+ Interactive: false,
+ },
+ Expected: func(t *testing.T, vars *types.BuildVars) {
+ assert.Equal(t, vars.Name, "foo")
+ assert.Equal(t, vars.Description, "Foo package")
+ },
+ }} {
+ t.Run(tc.Name, func(t *testing.T) {
+ cfg := &TestConfig{}
+ pf := &TestPackageFinder{}
+ info := &distro.OSRelease{}
- return env
- },
- Expected: func(t *testing.T, e *testEnv, res []string, err error) {
- assert.NoError(t, err)
- assert.Len(t, res, 2)
- assert.ElementsMatch(t, res, []string{"bar-pkg", "buz-pkg"})
-
- assert.ElementsMatch(t, e.capturedPkgs, []string{"bar", "buz"})
- },
- },
- */
- } {
- t.Run(tc.Name, func(tt *testing.T) {
ctx := context.Background()
- env := tc.Prepare()
- result, err := installBuildDeps(
+ b := NewBuilder(
ctx,
- env.pf,
- env.vars,
- env.opts,
+ tc.Opts,
+ pf,
+ info,
+ cfg,
)
- tc.Expected(tt, env, result, err)
+ fl, err := syntax.NewParser().Parse(strings.NewReader(tc.Script), "alr.sh")
+ assert.NoError(t, err)
+
+ vars, err := b.executeFirstPass(fl)
+ assert.NoError(t, err)
+
+ tc.Expected(t, vars)
})
}
}
diff --git a/pkg/build/install.go b/pkg/build/install.go
deleted file mode 100644
index bdb8c2e..0000000
--- a/pkg/build/install.go
+++ /dev/null
@@ -1,99 +0,0 @@
-// This file was originally part of the project "LURE - Linux User REpository", created by Elara Musayelyan.
-// It has been modified as part of "ALR - Any Linux Repository" by Евгений Храмов.
-//
-// 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 build
-
-import (
- "context"
- "log/slog"
- "os"
- "path/filepath"
-
- "github.com/leonelquinteros/gotext"
-
- "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/internal/types"
- "gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
- "gitea.plemya-x.ru/Plemya-x/ALR/pkg/repos"
-)
-
-// InstallPkgs устанавливает нативные пакеты с использованием менеджера пакетов,
-// затем строит и устанавливает пакеты ALR
-func InstallPkgs(ctx context.Context, alrPkgs []db.Package, nativePkgs []string, opts types.BuildOpts) {
- if len(nativePkgs) > 0 {
- err := opts.Manager.Install(nil, nativePkgs...)
- // Если есть нативные пакеты, выполняем их установку
- if err != nil {
- slog.Error(gotext.Get("Error installing native packages"), "err", err)
- os.Exit(1)
- // Логируем и завершаем выполнение при ошибке
- }
- }
-
- InstallALRPackages(ctx, alrPkgs, opts)
- // Устанавливаем скрипты сборки через функцию InstallScripts
-}
-
-func UpdateOpts(ctx context.Context, opts *types.BuildOpts, pkg *db.Package) {
- repodir := config.GetPaths(ctx).RepoDir
- if pkg.BasePkgName != "" {
- opts.Script = filepath.Join(repodir, pkg.Repository, pkg.BasePkgName, "alr.sh")
- opts.Package = pkg.Name
- } else {
- opts.Script = filepath.Join(repodir, pkg.Repository, pkg.Name, "alr.sh")
- }
-}
-
-// InstallALRPackages строит и устанавливает переданные alr скрипты сборки
-func InstallALRPackages(ctx context.Context, pkgs []db.Package, opts types.BuildOpts) {
- info, err := distro.ParseOSRelease(ctx)
- if err != nil {
- slog.Error(gotext.Get("Error parsing os release"), "err", err)
- os.Exit(1)
- }
-
- for _, pkg := range pkgs {
- UpdateOpts(ctx, &opts, &pkg)
-
- builder := New(
- ctx,
- opts,
- repos.GetInstance(ctx),
- info,
- config.GetInstance(ctx),
- )
-
- builtPkgs, _, err := builder.BuildPackage(ctx)
- // Выполняем сборку пакета
- if err != nil {
- slog.Error(gotext.Get("Error building package"), "err", err)
- os.Exit(1)
- // Логируем и завершаем выполнение при ошибке сборки
- }
-
- err = opts.Manager.InstallLocal(nil, builtPkgs...)
- // Устанавливаем локально собранные пакеты
- if err != nil {
- slog.Error(gotext.Get("Error installing package"), "err", err)
- os.Exit(1)
- // Логируем и завершаем выполнение при ошибке установки
- }
- }
-}
diff --git a/pkg/build/build_legacy.go b/pkg/build/utils.go
similarity index 81%
rename from pkg/build/build_legacy.go
rename to pkg/build/utils.go
index aee4286..e4e879a 100644
--- a/pkg/build/build_legacy.go
+++ b/pkg/build/utils.go
@@ -1,6 +1,3 @@
-// This file was originally part of the project "LURE - Linux User REpository", created by Elara Musayelyan.
-// It has been modified as part of "ALR - Any Linux Repository" by Евгений Храмов.
-//
// ALR - Any Linux Repository
// Copyright (C) 2025 Евгений Храмов
//
@@ -43,7 +40,6 @@ import (
"github.com/goreleaser/nfpm/v2"
"github.com/goreleaser/nfpm/v2/files"
- "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cpu"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/overrides"
@@ -82,62 +78,6 @@ func prepareDirs(dirs types.Directories) error {
return os.MkdirAll(dirs.PkgDir, 0o755) // Создаем директорию для пакетов
}
-type PackageFinder interface {
- FindPkgs(ctx context.Context, pkgs []string) (map[string][]db.Package, []string, error)
-}
-
-// Функция installBuildDeps устанавливает все зависимости сборки, которые еще не установлены, и возвращает
-// срез, содержащий имена всех установленных пакетов.
-func installBuildDeps(ctx context.Context, repos PackageFinder, vars *types.BuildVars, opts types.BuildOpts) ([]string, error) {
- var buildDeps []string
- if len(vars.BuildDepends) > 0 {
- deps, err := removeAlreadyInstalled(opts, vars.BuildDepends)
- if err != nil {
- return nil, err
- }
-
- found, notFound, err := repos.FindPkgs(ctx, deps) // Находим пакеты-зависимости
- if err != nil {
- return nil, err
- }
-
- slog.Info(gotext.Get("Installing build dependencies")) // Логгируем установку зависимостей
-
- flattened := cliutils.FlattenPkgs(ctx, found, "install", opts.Interactive) // Уплощаем список зависимостей
- buildDeps = packageNames(flattened)
- InstallPkgs(ctx, flattened, notFound, opts) // Устанавливаем пакеты
- }
- return buildDeps, nil
-}
-
-// Функция installOptDeps спрашивает у пользователя, какие, если таковые имеются, опциональные зависимости он хочет установить.
-// Если пользователь решает установить какие-либо опциональные зависимости, выполняется их установка.
-func installOptDeps(ctx context.Context, repos PackageFinder, vars *types.BuildVars, opts types.BuildOpts) error {
- optDeps, err := removeAlreadyInstalled(opts, vars.OptDepends)
- if err != nil {
- return err
- }
- if len(optDeps) > 0 {
- optDeps, err := cliutils.ChooseOptDepends(ctx, optDeps, "install", opts.Interactive) // Пользователя просят выбрать опциональные зависимости
- if err != nil {
- return err
- }
-
- if len(optDeps) == 0 {
- return nil
- }
-
- found, notFound, err := repos.FindPkgs(ctx, optDeps) // Находим опциональные зависимости
- if err != nil {
- return err
- }
-
- flattened := cliutils.FlattenPkgs(ctx, found, "install", opts.Interactive)
- InstallPkgs(ctx, flattened, notFound, opts) // Устанавливаем выбранные пакеты
- }
- return nil
-}
-
// Функция buildPkgMetadata создает метаданные для пакета, который будет собран.
func buildPkgMetadata(
ctx context.Context,
diff --git a/pkg/repos/repos_legacy.go b/pkg/repos/repos_legacy.go
index 046b6fb..d9f0973 100644
--- a/pkg/repos/repos_legacy.go
+++ b/pkg/repos/repos_legacy.go
@@ -40,7 +40,7 @@ func Pull(ctx context.Context, repos []types.Repo) error {
// It also returns a slice that contains the names of all packages that were not found.
//
// Deprecated: use struct method
-func FindPkgs(ctx context.Context, pkgs []string) (map[string][]database.Package, []string, error) {
+func FindPkgs_(ctx context.Context, pkgs []string) (map[string][]database.Package, []string, error) {
return GetInstance(ctx).FindPkgs(ctx, pkgs)
}
diff --git a/upgrade.go b/upgrade.go
index e7b152a..553cf41 100644
--- a/upgrade.go
+++ b/upgrade.go
@@ -32,7 +32,7 @@ import (
"golang.org/x/exp/slices"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
- "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
+ database "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/overrides"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/build"
@@ -56,7 +56,14 @@ func UpgradeCmd() *cli.Command {
Action: func(c *cli.Context) error {
ctx := c.Context
- cfg := config.GetInstance(ctx)
+ cfg := config.New()
+ db := database.New(cfg)
+ rs := repos.New(cfg, db)
+ err := db.Init(ctx)
+ if err != nil {
+ slog.Error(gotext.Get("Error db init"), "err", err)
+ os.Exit(1)
+ }
info, err := distro.ParseOSRelease(ctx)
if err != nil {
@@ -71,21 +78,32 @@ func UpgradeCmd() *cli.Command {
}
if cfg.AutoPull(ctx) {
- err = repos.Pull(ctx, config.Config(ctx).Repos)
+ err = rs.Pull(ctx, cfg.Repos(ctx))
if err != nil {
slog.Error(gotext.Get("Error pulling repos"), "err", err)
os.Exit(1)
}
}
- updates, err := checkForUpdates(ctx, mgr, info)
+ updates, err := checkForUpdates(ctx, mgr, cfg, rs, info)
if err != nil {
slog.Error(gotext.Get("Error checking for updates"), "err", err)
os.Exit(1)
}
if len(updates) > 0 {
- build.InstallPkgs(ctx, updates, nil, types.BuildOpts{
+ builder := build.NewBuilder(
+ ctx,
+ types.BuildOpts{
+ Manager: mgr,
+ Clean: c.Bool("clean"),
+ Interactive: c.Bool("interactive"),
+ },
+ rs,
+ info,
+ cfg,
+ )
+ builder.InstallPkgs(ctx, updates, nil, types.BuildOpts{
Manager: mgr,
Clean: c.Bool("clean"),
Interactive: c.Bool("interactive"),
@@ -99,27 +117,33 @@ func UpgradeCmd() *cli.Command {
}
}
-func checkForUpdates(ctx context.Context, mgr manager.Manager, info *distro.OSRelease) ([]db.Package, error) {
+func checkForUpdates(
+ ctx context.Context,
+ mgr manager.Manager,
+ cfg *config.ALRConfig,
+ rs *repos.Repos,
+ info *distro.OSRelease,
+) ([]database.Package, error) {
installed, err := mgr.ListInstalled(nil)
if err != nil {
return nil, err
}
pkgNames := maps.Keys(installed)
- found, _, err := repos.FindPkgs(ctx, pkgNames)
+ found, _, err := rs.FindPkgs(ctx, pkgNames)
if err != nil {
return nil, err
}
- var out []db.Package
+ var out []database.Package
for pkgName, pkgs := range found {
- if slices.Contains(config.Config(ctx).IgnorePkgUpdates, pkgName) {
+ if slices.Contains(cfg.IgnorePkgUpdates(ctx), pkgName) {
continue
}
if len(pkgs) > 1 {
// Puts the element with the highest version first
- slices.SortFunc(pkgs, func(a, b db.Package) int {
+ slices.SortFunc(pkgs, func(a, b database.Package) int {
return vercmp.Compare(a.Version, b.Version)
})
}