wip: add support of building multiple packages at once

This commit is contained in:
Maxim Slipenko 2025-02-12 14:11:46 +03:00
parent 083df3c7aa
commit e773e3ee12
7 changed files with 309 additions and 218 deletions

@ -76,7 +76,8 @@ func BuildCmd() *cli.Command {
os.Exit(1)
}
var script, packageName string
var script string
var packages []string
// Проверяем, установлен ли флаг script (-s)
@ -85,7 +86,7 @@ func BuildCmd() *cli.Command {
switch {
case c.IsSet("script"):
script = c.String("script")
packageName = c.String("script-package")
packages = append(packages, c.String("script-package"))
case c.IsSet("package"):
// TODO: handle multiple packages
packageInput := c.String("package")
@ -107,7 +108,7 @@ func BuildCmd() *cli.Command {
if pkg[0].BasePkgName != "" {
script = filepath.Join(repoDir, pkg[0].Repository, pkg[0].BasePkgName, "alr.sh")
packageName = pkg[0].Name
packages = append(packages, pkg[0].Name)
} else {
script = filepath.Join(repoDir, pkg[0].Repository, pkg[0].Name, "alr.sh")
}
@ -140,7 +141,7 @@ func BuildCmd() *cli.Command {
builder := build.NewBuilder(
ctx,
types.BuildOpts{
Package: packageName,
Packages: packages,
Script: script,
Manager: mgr,
Clean: c.Bool("clean"),

@ -34,31 +34,31 @@ msgstr ""
msgid "Error db init"
msgstr ""
#: build.go:104
#: build.go:105
msgid "Package not found"
msgstr ""
#: build.go:122
#: build.go:123
msgid "Error pulling repositories"
msgstr ""
#: build.go:130
#: build.go:131
msgid "Unable to detect a supported package manager on the system"
msgstr ""
#: build.go:136
#: build.go:137
msgid "Error parsing os release"
msgstr ""
#: build.go:157
#: build.go:158
msgid "Error building package"
msgstr ""
#: build.go:164
#: build.go:165
msgid "Error getting working directory"
msgstr ""
#: build.go:173
#: build.go:174
msgid "Error moving the package"
msgstr ""
@ -309,77 +309,69 @@ msgstr ""
msgid "Error while running app"
msgstr ""
#: pkg/build/build.go:135
#: pkg/build/build.go:153
msgid "Failed to prompt user to view build script"
msgstr ""
#: pkg/build/build.go:139
#: pkg/build/build.go:157
msgid "Building package"
msgstr ""
#: pkg/build/build.go:183
#: pkg/build/build.go:228
msgid "Downloading sources"
msgstr ""
#: pkg/build/build.go:195
#: pkg/build/build.go:246
msgid "Building package metadata"
msgstr ""
#: pkg/build/build.go:217
#: pkg/build/build.go:268
msgid "Compressing package"
msgstr ""
#: pkg/build/build.go:359
#: pkg/build/build.go:419
msgid ""
"Your system's CPU architecture doesn't match this package. Do you want to "
"build anyway?"
msgstr ""
#: pkg/build/build.go:373
#: pkg/build/build.go:433
msgid "This package is already installed"
msgstr ""
#: pkg/build/build.go:397
#: pkg/build/build.go:457
msgid "Installing build dependencies"
msgstr ""
#: pkg/build/build.go:408
#: pkg/build/build.go:468
msgid "Installing dependencies"
msgstr ""
#: pkg/build/build.go:449
#: pkg/build/build.go:521
msgid "The checksums array must be the same length as sources"
msgstr ""
#: pkg/build/build.go:500
#: pkg/build/build.go:572
msgid "Would you like to remove the build dependencies?"
msgstr ""
#: pkg/build/build.go:537
msgid "Executing version()"
msgstr ""
#: pkg/build/build.go:557
msgid "Updating version"
msgstr ""
#: pkg/build/build.go:562
#: pkg/build/build.go:635
msgid "Executing prepare()"
msgstr ""
#: pkg/build/build.go:572
#: pkg/build/build.go:645
msgid "Executing build()"
msgstr ""
#: pkg/build/build.go:588 pkg/build/build.go:616
#: pkg/build/build.go:675 pkg/build/build.go:695
msgid "Executing %s()"
msgstr ""
#: pkg/build/build.go:675
#: pkg/build/build.go:754
msgid "Error installing native packages"
msgstr ""
#: pkg/build/build.go:701
#: pkg/build/build.go:795
msgid "Error installing package"
msgstr ""
@ -395,11 +387,11 @@ msgstr ""
msgid "Required dependency found"
msgstr ""
#: pkg/build/utils.go:136
#: pkg/build/utils.go:133
msgid "AutoProv is not implemented for this package format, so it's skipped"
msgstr ""
#: pkg/build/utils.go:147
#: pkg/build/utils.go:144
msgid "AutoReq is not implemented for this package format, so it's skipped"
msgstr ""

@ -41,32 +41,32 @@ msgstr "Создайте пакет с нуля, даже если уже име
msgid "Error db init"
msgstr ""
#: build.go:104
#: build.go:105
msgid "Package not found"
msgstr ""
#: build.go:122
#: build.go:123
msgid "Error pulling repositories"
msgstr "Ошибка при извлечении репозиториев"
#: build.go:130
#: build.go:131
msgid "Unable to detect a supported package manager on the system"
msgstr "Не удалось обнаружить поддерживаемый менеджер пакетов в системе"
#: build.go:136
#: build.go:137
#, fuzzy
msgid "Error parsing os release"
msgstr "Ошибка при разборе файла выпуска операционной системы"
#: build.go:157
#: build.go:158
msgid "Error building package"
msgstr "Ошибка при сборке пакета"
#: build.go:164
#: build.go:165
msgid "Error getting working directory"
msgstr "Ошибка при получении рабочего каталога"
#: build.go:173
#: build.go:174
msgid "Error moving the package"
msgstr "Ошибка при перемещении пакета"
@ -324,27 +324,27 @@ msgstr ""
msgid "Error while running app"
msgstr "Ошибка при запуске приложения"
#: pkg/build/build.go:135
#: pkg/build/build.go:153
msgid "Failed to prompt user to view build script"
msgstr "Не удалось предложить пользователю просмотреть скрипт сборки"
#: pkg/build/build.go:139
#: pkg/build/build.go:157
msgid "Building package"
msgstr "Сборка пакета"
#: pkg/build/build.go:183
#: pkg/build/build.go:228
msgid "Downloading sources"
msgstr "Скачивание источников"
#: pkg/build/build.go:195
#: pkg/build/build.go:246
msgid "Building package metadata"
msgstr "Сборка метаданных пакета"
#: pkg/build/build.go:217
#: pkg/build/build.go:268
msgid "Compressing package"
msgstr "Сжатие пакета"
#: pkg/build/build.go:359
#: pkg/build/build.go:419
msgid ""
"Your system's CPU architecture doesn't match this package. Do you want to "
"build anyway?"
@ -352,52 +352,44 @@ msgstr ""
"Архитектура процессора вашей системы не соответствует этому пакету. Вы все "
"равно хотите выполнить сборку?"
#: pkg/build/build.go:373
#: pkg/build/build.go:433
msgid "This package is already installed"
msgstr "Этот пакет уже установлен"
#: pkg/build/build.go:397
#: pkg/build/build.go:457
msgid "Installing build dependencies"
msgstr "Установка зависимостей сборки"
#: pkg/build/build.go:408
#: pkg/build/build.go:468
msgid "Installing dependencies"
msgstr "Установка зависимостей"
#: pkg/build/build.go:449
#: pkg/build/build.go:521
msgid "The checksums array must be the same length as sources"
msgstr "Массив контрольных сумм должен быть той же длины, что и источники"
#: pkg/build/build.go:500
#: pkg/build/build.go:572
msgid "Would you like to remove the build dependencies?"
msgstr "Хотели бы вы удалить зависимости сборки?"
#: pkg/build/build.go:537
msgid "Executing version()"
msgstr "Исполнение версия()"
#: pkg/build/build.go:557
msgid "Updating version"
msgstr "Обновление версии"
#: pkg/build/build.go:562
#: pkg/build/build.go:635
msgid "Executing prepare()"
msgstr "Исполнение prepare()"
#: pkg/build/build.go:572
#: pkg/build/build.go:645
msgid "Executing build()"
msgstr "Исполнение build()"
#: pkg/build/build.go:588 pkg/build/build.go:616
#: pkg/build/build.go:675 pkg/build/build.go:695
#, fuzzy
msgid "Executing %s()"
msgstr "Исполнение files()"
#: pkg/build/build.go:675
#: pkg/build/build.go:754
msgid "Error installing native packages"
msgstr "Ошибка при установке нативных пакетов"
#: pkg/build/build.go:701
#: pkg/build/build.go:795
msgid "Error installing package"
msgstr "Ошибка при установке пакета"
@ -413,12 +405,12 @@ msgstr "Найденная предоставленная зависимость
msgid "Required dependency found"
msgstr "Найдена требуемая зависимость"
#: pkg/build/utils.go:136
#: pkg/build/utils.go:133
msgid "AutoProv is not implemented for this package format, so it's skipped"
msgstr ""
"AutoProv не реализовано для этого формата пакета, поэтому будет пропущено"
#: pkg/build/utils.go:147
#: pkg/build/utils.go:144
msgid "AutoReq is not implemented for this package format, so it's skipped"
msgstr ""
"AutoReq не реализовано для этого формата пакета, поэтому будет пропущено"
@ -499,5 +491,11 @@ msgstr "Ошибка при проверке обновлений"
msgid "There is nothing to do."
msgstr "Здесь нечего делать."
#~ msgid "Executing version()"
#~ msgstr "Исполнение версия()"
#~ msgid "Updating version"
#~ msgstr "Обновление версии"
#~ msgid "Executing package()"
#~ msgstr "Исполнение package()"

@ -23,7 +23,7 @@ import "gitea.plemya-x.ru/Plemya-x/ALR/pkg/manager"
type BuildOpts struct {
Script string
Package string
Packages []string
Manager manager.Manager
Clean bool
Interactive bool

@ -85,11 +85,11 @@ func NewBuilder(
}
}
func (b *Builder) UpdateOptsFromPkg(pkg *db.Package) {
func (b *Builder) UpdateOptsFromPkg(pkg *db.Package, packages []string) {
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
b.opts.Packages = packages
} else {
b.opts.Script = filepath.Join(repodir, pkg.Repository, pkg.Name, "alr.sh")
}
@ -103,23 +103,41 @@ func (b *Builder) BuildPackage(ctx context.Context) ([]string, []string, error)
// Первый проход предназначен для получения значений переменных и выполняется
// до отображения скрипта, чтобы предотвратить выполнение вредоносного кода.
vars, err := b.executeFirstPass(fl)
basePkg, varsOfPackages, err := b.executeFirstPass(fl)
if err != nil {
return nil, nil, err
}
dirs := b.getDirs(vars)
dirs := b.getDirs(basePkg)
builtPaths := make([]string, 0)
// Если флаг opts.Clean не установлен, и пакет уже собран,
// возвращаем его, а не собираем заново.
if !b.opts.Clean {
builtPkgPath, ok, err := checkForBuiltPackage(b.opts.Manager, vars, getPkgFormat(b.opts.Manager), dirs.BaseDir)
var remainingVars []*types.BuildVars
for _, vars := range varsOfPackages {
builtPkgPath, ok, err := checkForBuiltPackage(
b.opts.Manager,
vars,
getPkgFormat(b.opts.Manager),
dirs.BaseDir,
b.info,
)
if err != nil {
return nil, nil, err
}
if ok {
return []string{builtPkgPath}, nil, err
builtPaths = append(builtPaths, builtPkgPath)
} else {
remainingVars = append(remainingVars, vars)
}
}
if len(remainingVars) == 0 {
return builtPaths, nil, nil
}
}
@ -127,7 +145,7 @@ func (b *Builder) BuildPackage(ctx context.Context) ([]string, []string, error)
err = cliutils.PromptViewScript(
ctx,
b.opts.Script,
vars.Name,
basePkg,
b.config.PagerStyle(ctx),
b.opts.Interactive,
)
@ -136,7 +154,7 @@ func (b *Builder) BuildPackage(ctx context.Context) ([]string, []string, error)
os.Exit(1)
}
slog.Info(gotext.Get("Building package"), "name", vars.Name, "version", vars.Version)
slog.Info(gotext.Get("Building package"), "name", basePkg)
// Второй проход будет использоваться для выполнения реального кода,
// поэтому он не ограничен. Скрипт уже был показан
@ -152,12 +170,14 @@ func (b *Builder) BuildPackage(ctx context.Context) ([]string, []string, error)
return nil, nil, err
}
for _, vars := range varsOfPackages {
cont, err := b.performChecks(ctx, vars, installed) // Выполняем различные проверки
if err != nil {
return nil, nil, err
} else if !cont {
os.Exit(1) // Если проверки не пройдены, выходим из программы
}
}
// Подготавливаем директории для сборки
err = prepareDirs(dirs)
@ -165,34 +185,65 @@ func (b *Builder) BuildPackage(ctx context.Context) ([]string, []string, error)
return nil, nil, err
}
buildDeps, err := b.installBuildDeps(ctx, vars) // Устанавливаем зависимости для сборки
buildDepends := []string{}
optDepends := []string{}
depends := []string{}
sources := []string{}
checksums := []string{}
for _, vars := range varsOfPackages {
buildDepends = append(buildDepends, vars.BuildDepends...)
optDepends = append(optDepends, vars.OptDepends...)
depends = append(depends, vars.Depends...)
sources = append(sources, vars.Sources...)
checksums = append(checksums, vars.Checksums...)
}
buildDepends = removeDuplicates(buildDepends)
optDepends = removeDuplicates(optDepends)
depends = removeDuplicates(depends)
sources = removeDuplicates(sources)
checksums = removeDuplicates(checksums)
mergedVars := types.BuildVars{
Sources: sources,
Checksums: checksums,
}
buildDeps, err := b.installBuildDeps(ctx, buildDepends) // Устанавливаем зависимости для сборки
if err != nil {
return nil, nil, err
}
err = b.installOptDeps(ctx, vars) // Устанавливаем опциональные зависимости
err = b.installOptDeps(ctx, optDepends) // Устанавливаем опциональные зависимости
if err != nil {
return nil, nil, err
}
builtPaths, builtNames, repoDeps, err := b.buildALRDeps(ctx, vars) // Собираем зависимости
newBuildPaths, builtNames, repoDeps, err := b.buildALRDeps(ctx, depends) // Собираем зависимости
if err != nil {
return nil, nil, err
}
builtPaths = append(builtPaths, newBuildPaths...)
slog.Info(gotext.Get("Downloading sources")) // Записываем в лог загрузку источников
err = b.getSources(ctx, dirs, vars) // Загружаем исходники
err = b.getSources(ctx, dirs, &mergedVars) // Загружаем исходники
if err != nil {
return nil, nil, err
}
funcOut, err := b.executeFunctions(ctx, dec, dirs, vars) // Выполняем специальные функции
err = b.executeFunctions(ctx, dec, dirs) // Выполняем специальные функции
if err != nil {
return nil, nil, err
}
slog.Info(gotext.Get("Building package metadata"), "name", vars.Name)
for _, vars := range varsOfPackages {
funcOut, err := b.executePackageFunctions(ctx, dec, dirs, vars.Name)
if err != nil {
return nil, nil, err
}
slog.Info(gotext.Get("Building package metadata"), "name", basePkg)
pkgFormat := getPkgFormat(b.opts.Manager) // Получаем формат пакета
@ -221,15 +272,16 @@ func (b *Builder) BuildPackage(ctx context.Context) ([]string, []string, error)
return nil, nil, err
}
err = b.removeBuildDeps(ctx, buildDeps) // Удаляем зависимости для сборки
if err != nil {
return nil, nil, err
}
// Добавляем путь и имя только что собранного пакета в
// соответствующие срезы
builtPaths = append(builtPaths, pkgPath)
builtNames = append(builtNames, vars.Name)
}
err = b.removeBuildDeps(ctx, buildDeps) // Удаляем зависимости для сборки
if err != nil {
return nil, nil, err
}
// Удаляем дубликаты из pkgPaths и pkgNames.
// Дубликаты могут появиться, если несколько зависимостей
@ -244,7 +296,9 @@ func (b *Builder) BuildPackage(ctx context.Context) ([]string, []string, error)
// чтобы извлечь переменные сборки без выполнения реального кода.
func (b *Builder) executeFirstPass(
fl *syntax.File,
) (*types.BuildVars, error) {
) (string, []*types.BuildVars, error) {
varsOfPackages := []*types.BuildVars{}
scriptDir := filepath.Dir(b.opts.Script) // Получаем директорию скрипта
env := createBuildEnvVars(b.info, types.Directories{ScriptDir: scriptDir}) // Создаём переменные окружения для сборки
@ -257,12 +311,12 @@ func (b *Builder) executeFirstPass(
interp.OpenHandler(handlers.RestrictedOpen(scriptDir)), // Ограничиваем открытие файлов
)
if err != nil {
return nil, err
return "", nil, err
}
err = runner.Run(b.ctx, fl) // Запускаем скрипт
if err != nil {
return nil, err
return "", nil, err
}
dec := decoder.New(b.info, runner) // Создаём новый декодер
@ -275,47 +329,53 @@ func (b *Builder) executeFirstPass(
var pkgs packages
err = dec.DecodeVars(&pkgs)
if err != nil {
return nil, err
return "", nil, err
}
if len(pkgs.Names) == 0 {
return nil, errors.New("package name is missing")
return "", nil, errors.New("package name is missing")
}
var vars types.BuildVars
if len(pkgs.Names) == 1 {
err = dec.DecodeVars(&vars) // Декодируем переменные
if err != nil {
return nil, err
return "", nil, err
}
return &vars, nil
varsOfPackages = append(varsOfPackages, &vars)
return vars.Name, varsOfPackages, nil
}
if b.opts.Package == "" {
return nil, errors.New("script has multiple packages but package is not specified")
if len(b.opts.Packages) == 0 {
return "", nil, errors.New("script has multiple packages but package is not specified")
}
for _, pkgName := range b.opts.Packages {
var preVars types.BuildVarsPre
funcName := fmt.Sprintf("meta_%s", b.opts.Package)
funcName := fmt.Sprintf("meta_%s", pkgName)
meta, ok := dec.GetFuncSub(funcName)
if !ok {
return nil, errors.New("func is missing")
return "", nil, errors.New("func is missing")
}
r, err := meta(b.ctx)
if err != nil {
return nil, err
return "", nil, err
}
d := decoder.New(&distro.OSRelease{}, r)
err = d.DecodeVars(&preVars)
if err != nil {
return nil, err
return "", nil, err
}
vars = preVars.ToBuildVars()
vars.Name = b.opts.Package
vars := preVars.ToBuildVars()
vars.Name = pkgName
return &vars, nil // Возвращаем переменные сборки
varsOfPackages = append(varsOfPackages, &vars)
}
return pkgs.BasePkgName, varsOfPackages, nil // Возвращаем переменные сборки
}
// Функция getDirs возвращает соответствующие директории для скрипта
func (b *Builder) getDirs(vars *types.BuildVars) types.Directories {
baseDir := filepath.Join(b.config.GetPaths(b.ctx).PkgsDir, vars.Name) // Определяем базовую директорию
func (b *Builder) getDirs(basePkg string) types.Directories {
baseDir := filepath.Join(b.config.GetPaths(b.ctx).PkgsDir, basePkg) // Определяем базовую директорию
return types.Directories{
BaseDir: baseDir,
SrcDir: filepath.Join(baseDir, "src"),
@ -381,10 +441,10 @@ func (b *Builder) performChecks(ctx context.Context, vars *types.BuildVars, inst
// Функция installBuildDeps устанавливает все зависимости сборки, которые еще не установлены, и возвращает
// срез, содержащий имена всех установленных пакетов.
func (b *Builder) installBuildDeps(ctx context.Context, vars *types.BuildVars) ([]string, error) {
func (b *Builder) installBuildDeps(ctx context.Context, buildDepends []string) ([]string, error) {
var buildDeps []string
if len(vars.BuildDepends) > 0 {
deps, err := removeAlreadyInstalled(b.opts, vars.BuildDepends)
if len(buildDepends) > 0 {
deps, err := removeAlreadyInstalled(b.opts, buildDepends)
if err != nil {
return nil, err
}
@ -403,11 +463,11 @@ func (b *Builder) installBuildDeps(ctx context.Context, vars *types.BuildVars) (
return buildDeps, nil
}
func (b *Builder) buildALRDeps(ctx context.Context, vars *types.BuildVars) (builtPaths, builtNames, repoDeps []string, err error) {
if len(vars.Depends) > 0 {
func (b *Builder) buildALRDeps(ctx context.Context, depends []string) (builtPaths, builtNames, repoDeps []string, err error) {
if len(depends) > 0 {
slog.Info(gotext.Get("Installing dependencies"))
found, notFound, err := b.repos.FindPkgs(ctx, vars.Depends) // Поиск зависимостей
found, notFound, err := b.repos.FindPkgs(ctx, depends) // Поиск зависимостей
if err != nil {
return nil, nil, nil, err
}
@ -416,10 +476,24 @@ func (b *Builder) buildALRDeps(ctx context.Context, vars *types.BuildVars) (buil
// Если для некоторых пакетов есть несколько опций, упрощаем их все в один срез
pkgs := cliutils.FlattenPkgs(ctx, found, "install", b.opts.Interactive)
type x struct {
pkg *db.Package
packages []string
}
xx := make(map[string]*x)
for _, pkg := range pkgs {
if xx[pkg.BasePkgName] == nil {
xx[pkg.BasePkgName] = &x{
pkg: &pkg,
}
}
xx[pkg.BasePkgName].packages = append(xx[pkg.BasePkgName].packages, pkg.Name)
}
for basePkgName := range xx {
pkg := xx[basePkgName].pkg
newB := *b
newB.UpdateOptsFromPkg(&pkg)
newB.UpdateOptsFromPkg(pkg, xx[basePkgName].packages)
// Собираем зависимости
pkgPaths, pkgNames, err := newB.BuildPackage(ctx)
@ -431,8 +505,6 @@ func (b *Builder) buildALRDeps(ctx context.Context, vars *types.BuildVars) (buil
builtPaths = append(builtPaths, pkgPaths...)
// Добавляем пути всех собранных пакетов в builtPaths
builtNames = append(builtNames, pkgNames...)
// Добавляем имя текущего пакета в builtNames
builtNames = append(builtNames, filepath.Base(filepath.Dir(newB.opts.Script)))
}
}
@ -530,8 +602,8 @@ func (b *Builder) executeFunctions(
ctx context.Context,
dec *decoder.Decoder,
dirs types.Directories,
vars *types.BuildVars,
) (*FunctionsOutput, error) {
) error {
/*
version, ok := dec.GetFunc("version")
if ok {
slog.Info(gotext.Get("Executing version()"))
@ -556,6 +628,7 @@ func (b *Builder) executeFunctions(
slog.Info(gotext.Get("Updating version"), "new", newVer)
}
*/
prepare, ok := dec.GetFunc("prepare")
if ok {
@ -563,7 +636,7 @@ func (b *Builder) executeFunctions(
err := prepare(ctx, interp.Dir(dirs.SrcDir))
if err != nil {
return nil, err
return err
}
}
@ -573,15 +646,29 @@ func (b *Builder) executeFunctions(
err := build(ctx, interp.Dir(dirs.SrcDir))
if err != nil {
return nil, err
return err
}
}
return nil
}
func (b *Builder) executePackageFunctions(
ctx context.Context,
dec *decoder.Decoder,
dirs types.Directories,
packageName string,
) (*FunctionsOutput, error) {
output := &FunctionsOutput{}
var packageFuncName string
if b.opts.Package == "" {
var filesFuncName string
if packageName == "" {
filesFuncName = "files"
packageFuncName = "package"
} else {
packageFuncName = fmt.Sprintf("package_%s", b.opts.Package)
packageFuncName = fmt.Sprintf("package_%s", packageName)
filesFuncName = fmt.Sprintf("files_%s", packageName)
}
packageFn, ok := dec.GetFunc(packageFuncName)
if ok {
@ -592,14 +679,6 @@ func (b *Builder) executeFunctions(
}
}
output := &FunctionsOutput{}
var filesFuncName string
if b.opts.Package == "" {
filesFuncName = "files"
} else {
filesFuncName = fmt.Sprintf("files_%s", b.opts.Package)
}
files, ok := dec.GetFuncP(filesFuncName, func(ctx context.Context, s *interp.Runner) error {
// It should be done via interp.RunnerOption,
// but due to the issues below, it cannot be done.
@ -636,8 +715,8 @@ 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)
func (b *Builder) installOptDeps(ctx context.Context, optDepends []string) error {
optDeps, err := removeAlreadyInstalled(b.opts, optDepends)
if err != nil {
return err
}
@ -683,9 +762,24 @@ func (b *Builder) InstallPkgs(
}
func (b *Builder) InstallALRPackages(ctx context.Context, pkgs []db.Package, opts types.BuildOpts) {
type x struct {
pkg *db.Package
packages []string
}
xx := make(map[string]*x)
for _, pkg := range pkgs {
if xx[pkg.BasePkgName] == nil {
xx[pkg.BasePkgName] = &x{
pkg: &pkg,
}
}
xx[pkg.BasePkgName].packages = append(xx[pkg.BasePkgName].packages, pkg.Name)
}
for basePkgName := range xx {
pkg := xx[basePkgName].pkg
builder := *b
builder.UpdateOptsFromPkg(&pkg)
builder.UpdateOptsFromPkg(pkg, xx[basePkgName].packages)
builtPkgs, _, err := builder.BuildPackage(ctx)
// Выполняем сборку пакета

@ -191,7 +191,7 @@ rm -f %s`, tmpFilePath)
fl, err := syntax.NewParser().Parse(strings.NewReader(testScript), "alr.sh")
assert.NoError(t, err)
_, err = b.executeFirstPass(fl)
_, _, err = b.executeFirstPass(fl)
assert.NoError(t, err)
_, err = os.Stat(tmpFilePath)
@ -203,7 +203,7 @@ func TestExecuteFirstPassIsCorrect(t *testing.T) {
Name string
Script string
Opts types.BuildOpts
Expected func(t *testing.T, vars *types.BuildVars)
Expected func(t *testing.T, vars []*types.BuildVars)
}
for _, tc := range []testCase{{
@ -220,12 +220,13 @@ maintainer='Ivan Ivanov'
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")
Expected: func(t *testing.T, vars []*types.BuildVars) {
assert.Equal(t, 1, len(vars))
assert.Equal(t, vars[0].Name, "test")
assert.Equal(t, vars[0].Version, "1.0.0")
assert.Equal(t, vars[0].Release, int(1))
assert.Equal(t, vars[0].Epoch, uint(2))
assert.Equal(t, vars[0].Description, "Test package")
},
}, {
Name: "multiple packages",
@ -248,13 +249,14 @@ meta_bar() {
}
`,
Opts: types.BuildOpts{
Package: "foo",
Packages: []string{"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")
Expected: func(t *testing.T, vars []*types.BuildVars) {
assert.Equal(t, 1, len(vars))
assert.Equal(t, vars[0].Name, "foo")
assert.Equal(t, vars[0].Description, "Foo package")
},
}} {
t.Run(tc.Name, func(t *testing.T) {
@ -275,10 +277,10 @@ meta_bar() {
fl, err := syntax.NewParser().Parse(strings.NewReader(tc.Script), "alr.sh")
assert.NoError(t, err)
vars, err := b.executeFirstPass(fl)
_, allVars, err := b.executeFirstPass(fl)
assert.NoError(t, err)
tc.Expected(t, vars)
tc.Expected(t, allVars)
})
}
}

@ -34,7 +34,6 @@ import (
_ "github.com/goreleaser/nfpm/v2/deb"
_ "github.com/goreleaser/nfpm/v2/rpm"
"github.com/leonelquinteros/gotext"
"mvdan.cc/sh/v3/interp"
"mvdan.cc/sh/v3/syntax"
"github.com/goreleaser/nfpm/v2"
@ -88,7 +87,7 @@ func buildPkgMetadata(
deps []string,
preferedContents *[]string,
) (*nfpm.Info, error) {
pkgInfo := getBasePkgInfo(vars)
pkgInfo := getBasePkgInfo(vars, info)
pkgInfo.Description = vars.Description
pkgInfo.Platform = "linux"
pkgInfo.Homepage = vars.Homepage
@ -108,8 +107,6 @@ func buildPkgMetadata(
})
}
pkgInfo.Release = overrides.ReleasePlatformSpecific(vars.Release, info)
if vars.Epoch != 0 {
pkgInfo.Epoch = strconv.FormatUint(uint64(vars.Epoch), 10)
}
@ -249,8 +246,14 @@ func buildContents(vars *types.BuildVars, dirs types.Directories, preferedConten
// Функция checkForBuiltPackage пытается обнаружить ранее собранный пакет и вернуть его путь
// и true, если нашла. Если нет, возвратит "", false, nil.
func checkForBuiltPackage(mgr manager.Manager, vars *types.BuildVars, pkgFormat, baseDir string) (string, bool, error) {
filename, err := pkgFileName(vars, pkgFormat)
func checkForBuiltPackage(
mgr manager.Manager,
vars *types.BuildVars,
pkgFormat,
baseDir string,
info *distro.OSRelease,
) (string, bool, error) {
filename, err := pkgFileName(vars, pkgFormat, info)
if err != nil {
return "", false, err
}
@ -265,20 +268,20 @@ func checkForBuiltPackage(mgr manager.Manager, vars *types.BuildVars, pkgFormat,
return pkgPath, true, nil
}
func getBasePkgInfo(vars *types.BuildVars) *nfpm.Info {
func getBasePkgInfo(vars *types.BuildVars, info *distro.OSRelease) *nfpm.Info {
return &nfpm.Info{
Name: vars.Name,
Arch: cpu.Arch(),
Version: vars.Version,
Release: strconv.Itoa(vars.Release),
Release: overrides.ReleasePlatformSpecific(vars.Release, info),
Epoch: strconv.FormatUint(uint64(vars.Epoch), 10),
}
}
// pkgFileName returns the filename of the package if it were to be built.
// This is used to check if the package has already been built.
func pkgFileName(vars *types.BuildVars, pkgFormat string) (string, error) {
pkgInfo := getBasePkgInfo(vars)
func pkgFileName(vars *types.BuildVars, pkgFormat string, info *distro.OSRelease) (string, error) {
pkgInfo := getBasePkgInfo(vars, info)
packager, err := nfpm.Get(pkgFormat)
if err != nil {
@ -366,6 +369,7 @@ func setScripts(vars *types.BuildVars, info *nfpm.Info, scriptDir string) {
}
}
/*
// Функция setVersion изменяет переменную версии в скрипте runner.
// Она используется для установки версии на вывод функции version().
func setVersion(ctx context.Context, r *interp.Runner, to string) error {
@ -375,7 +379,7 @@ func setVersion(ctx context.Context, r *interp.Runner, to string) error {
}
return r.Run(ctx, fl)
}
*/
// Returns not installed dependencies
func removeAlreadyInstalled(opts types.BuildOpts, dependencies []string) ([]string, error) {
filteredPackages := []string{}