diff --git a/build.go b/build.go index 988b913..dc09827 100644 --- a/build.go +++ b/build.go @@ -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"), diff --git a/internal/translations/default.pot b/internal/translations/default.pot index 21b6ec6..d878495 100644 --- a/internal/translations/default.pot +++ b/internal/translations/default.pot @@ -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 "" diff --git a/internal/translations/po/ru/default.po b/internal/translations/po/ru/default.po index b89a540..dad9ff6 100644 --- a/internal/translations/po/ru/default.po +++ b/internal/translations/po/ru/default.po @@ -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()" diff --git a/internal/types/build.go b/internal/types/build.go index 7682115..a975e92 100644 --- a/internal/types/build.go +++ b/internal/types/build.go @@ -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 diff --git a/pkg/build/build.go b/pkg/build/build.go index 46fd9f5..facdc7a 100644 --- a/pkg/build/build.go +++ b/pkg/build/build.go @@ -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) - if err != nil { - return nil, nil, err + 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 { + builtPaths = append(builtPaths, builtPkgPath) + } else { + remainingVars = append(remainingVars, vars) + } } - if ok { - return []string{builtPkgPath}, nil, err + 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,11 +170,13 @@ func (b *Builder) BuildPackage(ctx context.Context) ([]string, []string, error) return nil, nil, err } - cont, err := b.performChecks(ctx, vars, installed) // Выполняем различные проверки - if err != nil { - return nil, nil, err - } else if !cont { - os.Exit(1) // Если проверки не пройдены, выходим из программы + for _, vars := range varsOfPackages { + cont, err := b.performChecks(ctx, vars, installed) // Выполняем различные проверки + if err != nil { + return nil, nil, err + } else if !cont { + os.Exit(1) // Если проверки не пройдены, выходим из программы + } } // Подготавливаем директории для сборки @@ -165,60 +185,97 @@ 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 + } - pkgFormat := getPkgFormat(b.opts.Manager) // Получаем формат пакета + slog.Info(gotext.Get("Building package metadata"), "name", basePkg) - pkgInfo, err := buildPkgMetadata(ctx, vars, dirs, pkgFormat, b.info, append(repoDeps, builtNames...), funcOut.Contents) // Собираем метаданные пакета - if err != nil { - return nil, nil, err - } + pkgFormat := getPkgFormat(b.opts.Manager) // Получаем формат пакета - packager, err := nfpm.Get(pkgFormat) // Получаем упаковщик для формата пакета - if err != nil { - return nil, nil, err - } + pkgInfo, err := buildPkgMetadata(ctx, vars, dirs, pkgFormat, b.info, append(repoDeps, builtNames...), funcOut.Contents) // Собираем метаданные пакета + if err != nil { + return nil, nil, err + } - pkgName := packager.ConventionalFileName(pkgInfo) // Получаем имя файла пакета - pkgPath := filepath.Join(dirs.BaseDir, pkgName) // Определяем путь к пакету + packager, err := nfpm.Get(pkgFormat) // Получаем упаковщик для формата пакета + if err != nil { + return nil, nil, err + } - pkgFile, err := os.Create(pkgPath) // Создаём файл пакета - if err != nil { - return nil, nil, err - } + pkgName := packager.ConventionalFileName(pkgInfo) // Получаем имя файла пакета + pkgPath := filepath.Join(dirs.BaseDir, pkgName) // Определяем путь к пакету - slog.Info(gotext.Get("Compressing package"), "name", pkgName) // Логгируем сжатие пакета + pkgFile, err := os.Create(pkgPath) // Создаём файл пакета + if err != nil { + return nil, nil, err + } - err = packager.Package(pkgInfo, pkgFile) // Упаковываем пакет - if err != nil { - return nil, nil, err + slog.Info(gotext.Get("Compressing package"), "name", pkgName) // Логгируем сжатие пакета + + err = packager.Package(pkgInfo, pkgFile) // Упаковываем пакет + if err != nil { + return nil, nil, err + } + + // Добавляем путь и имя только что собранного пакета в + // соответствующие срезы + builtPaths = append(builtPaths, pkgPath) + builtNames = append(builtNames, vars.Name) } err = b.removeBuildDeps(ctx, buildDeps) // Удаляем зависимости для сборки @@ -226,11 +283,6 @@ func (b *Builder) BuildPackage(ctx context.Context) ([]string, []string, error) return nil, nil, err } - // Добавляем путь и имя только что собранного пакета в - // соответствующие срезы - builtPaths = append(builtPaths, pkgPath) - builtNames = append(builtNames, vars.Name) - // Удаляем дубликаты из 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") } - var preVars types.BuildVarsPre - funcName := fmt.Sprintf("meta_%s", b.opts.Package) - meta, ok := dec.GetFuncSub(funcName) - if !ok { - return nil, errors.New("func is missing") - } - r, err := meta(b.ctx) - if err != nil { - return nil, err - } - d := decoder.New(&distro.OSRelease{}, r) - err = d.DecodeVars(&preVars) - if err != nil { - return nil, err - } - vars = preVars.ToBuildVars() - vars.Name = b.opts.Package + for _, pkgName := range b.opts.Packages { + var preVars types.BuildVarsPre + funcName := fmt.Sprintf("meta_%s", pkgName) + meta, ok := dec.GetFuncSub(funcName) + if !ok { + return "", nil, errors.New("func is missing") + } + r, err := meta(b.ctx) + if err != nil { + return "", nil, err + } + d := decoder.New(&distro.OSRelease{}, r) + err = d.DecodeVars(&preVars) + if err != nil { + return "", nil, err + } + 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,32 +602,33 @@ func (b *Builder) executeFunctions( ctx context.Context, dec *decoder.Decoder, dirs types.Directories, - vars *types.BuildVars, -) (*FunctionsOutput, error) { - version, ok := dec.GetFunc("version") - if ok { - slog.Info(gotext.Get("Executing version()")) +) error { + /* + version, ok := dec.GetFunc("version") + if ok { + slog.Info(gotext.Get("Executing version()")) - buf := &bytes.Buffer{} + buf := &bytes.Buffer{} - err := version( - ctx, - interp.Dir(dirs.SrcDir), - interp.StdIO(os.Stdin, buf, os.Stderr), - ) - if err != nil { - return nil, err + err := version( + ctx, + interp.Dir(dirs.SrcDir), + interp.StdIO(os.Stdin, buf, os.Stderr), + ) + if err != nil { + return nil, err + } + + newVer := strings.TrimSpace(buf.String()) + err = setVersion(ctx, dec.Runner, newVer) + if err != nil { + return nil, err + } + vars.Version = newVer + + slog.Info(gotext.Get("Updating version"), "new", newVer) } - - newVer := strings.TrimSpace(buf.String()) - err = setVersion(ctx, dec.Runner, newVer) - if err != nil { - return nil, err - } - vars.Version = newVer - - 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) // Выполняем сборку пакета diff --git a/pkg/build/build_internal_test.go b/pkg/build/build_internal_test.go index afffcbd..10fd80c 100644 --- a/pkg/build/build_internal_test.go +++ b/pkg/build/build_internal_test.go @@ -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) }) } } diff --git a/pkg/build/utils.go b/pkg/build/utils.go index e4e879a..3b3ba49 100644 --- a/pkg/build/utils.go +++ b/pkg/build/utils.go @@ -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{}