Merge pull request 'fix: use unique names for packages' (#40) from Maks1mS/ALR:fix/use-unique-package-name into master

Reviewed-on: Plemya-x/ALR#40
This commit is contained in:
Евгений Храмов 2025-03-02 06:49:52 +00:00
commit 71000fd3cd
10 changed files with 253 additions and 226 deletions

@ -78,8 +78,7 @@ func BuildCmd() *cli.Command {
var script string
var packages []string
// Проверяем, установлен ли флаг script (-s)
repository := "default"
repoDir := cfg.GetPaths(ctx).RepoDir
@ -106,11 +105,13 @@ func BuildCmd() *cli.Command {
os.Exit(1)
}
repository = pkg[0].Repository
if pkg[0].BasePkgName != "" {
script = filepath.Join(repoDir, pkg[0].Repository, pkg[0].BasePkgName, "alr.sh")
script = filepath.Join(repoDir, repository, pkg[0].BasePkgName, "alr.sh")
packages = append(packages, pkg[0].Name)
} else {
script = filepath.Join(repoDir, pkg[0].Repository, pkg[0].Name, "alr.sh")
script = filepath.Join(repoDir, repository, pkg[0].Name, "alr.sh")
}
default:
script = filepath.Join(repoDir, "alr.sh")
@ -142,6 +143,7 @@ func BuildCmd() *cli.Command {
ctx,
types.BuildOpts{
Packages: packages,
Repository: repository,
Script: script,
Manager: mgr,
Clean: c.Bool("clean"),

@ -193,3 +193,7 @@ func (c *ALRConfig) RootCmd(ctx context.Context) string {
})
return c.cfg.RootCmd
}
func (c *ALRConfig) Save(f *os.File) error {
return toml.NewEncoder(f).Encode(c.cfg)
}

@ -34,31 +34,31 @@ msgstr ""
msgid "Error initialization database"
msgstr ""
#: build.go:105
#: build.go:104
msgid "Package not found"
msgstr ""
#: build.go:123
#: build.go:124
msgid "Error pulling repositories"
msgstr ""
#: build.go:131
#: build.go:132
msgid "Unable to detect a supported package manager on the system"
msgstr ""
#: build.go:137
#: build.go:138
msgid "Error parsing os release"
msgstr ""
#: build.go:158
#: build.go:160
msgid "Error building package"
msgstr ""
#: build.go:165
#: build.go:167
msgid "Error getting working directory"
msgstr ""
#: build.go:174
#: build.go:176
msgid "Error moving the package"
msgstr ""
@ -323,11 +323,11 @@ msgstr ""
msgid "ERROR"
msgstr ""
#: list.go:40
#: list.go:41
msgid "List ALR repo packages"
msgstr ""
#: list.go:91
#: list.go:92
msgid "Error listing installed packages"
msgstr ""
@ -369,60 +369,68 @@ msgstr ""
msgid "Downloading sources"
msgstr ""
#: pkg/build/build.go:246
#: pkg/build/build.go:250
msgid "Building package metadata"
msgstr ""
#: pkg/build/build.go:268
#: pkg/build/build.go:272
msgid "Compressing package"
msgstr ""
#: pkg/build/build.go:421
#: pkg/build/build.go:426
msgid ""
"Your system's CPU architecture doesn't match this package. Do you want to "
"build anyway?"
msgstr ""
#: pkg/build/build.go:435
#: pkg/build/build.go:440
msgid "This package is already installed"
msgstr ""
#: pkg/build/build.go:459
#: pkg/build/build.go:464
msgid "Installing build dependencies"
msgstr ""
#: pkg/build/build.go:500
#: pkg/build/build.go:505
msgid "Installing dependencies"
msgstr ""
#: pkg/build/build.go:535
#: pkg/build/build.go:540
msgid "The checksums array must be the same length as sources"
msgstr ""
#: pkg/build/build.go:586
#: pkg/build/build.go:591
msgid "Would you like to remove the build dependencies?"
msgstr ""
#: pkg/build/build.go:649
#: pkg/build/build.go:654
msgid "Executing prepare()"
msgstr ""
#: pkg/build/build.go:659
#: pkg/build/build.go:664
msgid "Executing build()"
msgstr ""
#: pkg/build/build.go:689 pkg/build/build.go:709
#: pkg/build/build.go:694 pkg/build/build.go:714
msgid "Executing %s()"
msgstr ""
#: pkg/build/build.go:768
#: pkg/build/build.go:773
msgid "Error installing native packages"
msgstr ""
#: pkg/build/build.go:792
#: pkg/build/build.go:797
msgid "Error installing package"
msgstr ""
#: pkg/build/build.go:857
msgid "AutoProv is not implemented for this package format, so it's skipped"
msgstr ""
#: pkg/build/build.go:868
msgid "AutoReq is not implemented for this package format, so it's skipped"
msgstr ""
#: pkg/build/findDeps.go:35
msgid "Command not found on the system"
msgstr ""
@ -435,14 +443,6 @@ msgstr ""
msgid "Required dependency found"
msgstr ""
#: pkg/build/utils.go:133
msgid "AutoProv is not implemented for this package format, so it's skipped"
msgstr ""
#: pkg/build/utils.go:144
msgid "AutoReq is not implemented for this package format, so it's skipped"
msgstr ""
#: pkg/repos/pull.go:79
msgid "Pulling repository"
msgstr ""

@ -12,8 +12,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Gtranslator 47.1\n"
#: build.go:44
@ -41,31 +41,31 @@ msgstr "Создайте пакет с нуля, даже если уже име
msgid "Error initialization database"
msgstr "Ошибка инициализации базы данных"
#: build.go:105
#: build.go:104
msgid "Package not found"
msgstr "Пакет не найден"
#: build.go:123
#: build.go:124
msgid "Error pulling repositories"
msgstr "Ошибка при извлечении репозиториев"
#: build.go:131
#: build.go:132
msgid "Unable to detect a supported package manager on the system"
msgstr "Не удалось обнаружить поддерживаемый менеджер пакетов в системе"
#: build.go:137
#: build.go:138
msgid "Error parsing os release"
msgstr "Ошибка при разборе файла выпуска операционной системы"
#: build.go:158
#: build.go:160
msgid "Error building package"
msgstr "Ошибка при сборке пакета"
#: build.go:165
#: build.go:167
msgid "Error getting working directory"
msgstr "Ошибка при получении рабочего каталога"
#: build.go:174
#: build.go:176
msgid "Error moving the package"
msgstr "Ошибка при перемещении пакета"
@ -335,11 +335,11 @@ msgstr "%s %s загружается — %s/с\n"
msgid "ERROR"
msgstr "ОШИБКА"
#: list.go:40
#: list.go:41
msgid "List ALR repo packages"
msgstr "Список пакетов репозитория ALR"
#: list.go:91
#: list.go:92
msgid "Error listing installed packages"
msgstr "Ошибка при составлении списка установленных пакетов"
@ -383,15 +383,15 @@ msgstr "Сборка пакета"
msgid "Downloading sources"
msgstr "Скачивание источников"
#: pkg/build/build.go:246
#: pkg/build/build.go:250
msgid "Building package metadata"
msgstr "Сборка метаданных пакета"
#: pkg/build/build.go:268
#: pkg/build/build.go:272
msgid "Compressing package"
msgstr "Сжатие пакета"
#: pkg/build/build.go:421
#: pkg/build/build.go:426
msgid ""
"Your system's CPU architecture doesn't match this package. Do you want to "
"build anyway?"
@ -399,46 +399,56 @@ msgstr ""
"Архитектура процессора вашей системы не соответствует этому пакету. Вы все "
"равно хотите выполнить сборку?"
#: pkg/build/build.go:435
#: pkg/build/build.go:440
msgid "This package is already installed"
msgstr "Этот пакет уже установлен"
#: pkg/build/build.go:459
#: pkg/build/build.go:464
msgid "Installing build dependencies"
msgstr "Установка зависимостей сборки"
#: pkg/build/build.go:500
#: pkg/build/build.go:505
msgid "Installing dependencies"
msgstr "Установка зависимостей"
#: pkg/build/build.go:535
#: pkg/build/build.go:540
msgid "The checksums array must be the same length as sources"
msgstr "Массив контрольных сумм должен быть той же длины, что и источники"
#: pkg/build/build.go:586
#: pkg/build/build.go:591
msgid "Would you like to remove the build dependencies?"
msgstr "Хотели бы вы удалить зависимости сборки?"
#: pkg/build/build.go:649
#: pkg/build/build.go:654
msgid "Executing prepare()"
msgstr "Исполнение prepare()"
#: pkg/build/build.go:659
#: pkg/build/build.go:664
msgid "Executing build()"
msgstr "Исполнение build()"
#: pkg/build/build.go:689 pkg/build/build.go:709
#: pkg/build/build.go:694 pkg/build/build.go:714
msgid "Executing %s()"
msgstr "Исполнение %s()"
#: pkg/build/build.go:768
#: pkg/build/build.go:773
msgid "Error installing native packages"
msgstr "Ошибка при установке нативных пакетов"
#: pkg/build/build.go:792
#: pkg/build/build.go:797
msgid "Error installing package"
msgstr "Ошибка при установке пакета"
#: pkg/build/build.go:857
msgid "AutoProv is not implemented for this package format, so it's skipped"
msgstr ""
"AutoProv не реализовано для этого формата пакета, поэтому будет пропущено"
#: pkg/build/build.go:868
msgid "AutoReq is not implemented for this package format, so it's skipped"
msgstr ""
"AutoReq не реализовано для этого формата пакета, поэтому будет пропущено"
#: pkg/build/findDeps.go:35
msgid "Command not found on the system"
msgstr "Команда не найдена в системе"
@ -451,16 +461,6 @@ msgstr "Найденная предоставленная зависимость
msgid "Required dependency found"
msgstr "Найдена требуемая зависимость"
#: pkg/build/utils.go:133
msgid "AutoProv is not implemented for this package format, so it's skipped"
msgstr ""
"AutoProv не реализовано для этого формата пакета, поэтому будет пропущено"
#: pkg/build/utils.go:144
msgid "AutoReq is not implemented for this package format, so it's skipped"
msgstr ""
"AutoReq не реализовано для этого формата пакета, поэтому будет пропущено"
#: pkg/repos/pull.go:79
msgid "Pulling repository"
msgstr "Скачивание репозитория"

@ -23,6 +23,7 @@ import "gitea.plemya-x.ru/Plemya-x/ALR/pkg/manager"
type BuildOpts struct {
Script string
Repository string
Packages []string
Manager manager.Manager
Clean bool
@ -102,6 +103,7 @@ type BuildVars struct {
Scripts Scripts `sh:"scripts"`
AutoReq []string `sh:"auto_req"`
AutoProv []string `sh:"auto_prov"`
Base string
}
type Scripts struct {

16
list.go

@ -30,6 +30,7 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
database "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/build"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/manager"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/repos"
)
@ -78,7 +79,7 @@ func ListCmd() *cli.Command {
}
defer result.Close()
var installed map[string]string
installedAlrPackages := map[string]string{}
if c.Bool("installed") {
mgr := manager.Detect()
if mgr == nil {
@ -86,11 +87,20 @@ func ListCmd() *cli.Command {
os.Exit(1)
}
installed, err = mgr.ListInstalled(&manager.Opts{AsRoot: false})
installed, err := mgr.ListInstalled(&manager.Opts{AsRoot: false})
if err != nil {
slog.Error(gotext.Get("Error listing installed packages"), "err", err)
os.Exit(1)
}
for pkgName, version := range installed {
matches := build.RegexpALRPackageName.FindStringSubmatch(pkgName)
if matches != nil {
packageName := matches[build.RegexpALRPackageName.SubexpIndex("package")]
repoName := matches[build.RegexpALRPackageName.SubexpIndex("repo")]
installedAlrPackages[fmt.Sprintf("%s/%s", repoName, packageName)] = version
}
}
}
for result.Next() {
@ -106,7 +116,7 @@ func ListCmd() *cli.Command {
version := pkg.Version
if c.Bool("installed") {
instVersion, ok := installed[pkg.Name]
instVersion, ok := installedAlrPackages[fmt.Sprintf("%s/%s", pkg.Repository, pkg.Name)]
if !ok {
continue
} else {

@ -28,6 +28,8 @@ import (
"log/slog"
"os"
"path/filepath"
"slices"
"strconv"
"strings"
"time"
@ -87,6 +89,7 @@ func NewBuilder(
func (b *Builder) UpdateOptsFromPkg(pkg *db.Package, packages []string) {
repodir := b.config.GetPaths(b.ctx).RepoDir
b.opts.Repository = pkg.Repository
if pkg.BasePkgName != "" {
b.opts.Script = filepath.Join(repodir, pkg.Repository, pkg.BasePkgName, "alr.sh")
b.opts.Packages = packages
@ -116,14 +119,11 @@ func (b *Builder) BuildPackage(ctx context.Context) ([]string, []string, error)
// возвращаем его, а не собираем заново.
if !b.opts.Clean {
var remainingVars []*types.BuildVars
for _, vars := range varsOfPackages {
builtPkgPath, ok, err := checkForBuiltPackage(
b.opts.Manager,
builtPkgPath, ok, err := b.checkForBuiltPackage(
vars,
getPkgFormat(b.opts.Manager),
dirs.BaseDir,
b.info,
)
if err != nil {
return nil, nil, err
@ -238,7 +238,11 @@ func (b *Builder) BuildPackage(ctx context.Context) ([]string, []string, error)
}
for _, vars := range varsOfPackages {
funcOut, err := b.executePackageFunctions(ctx, dec, dirs, vars.Name)
packageName := ""
if vars.Base != "" {
packageName = vars.Name
}
funcOut, err := b.executePackageFunctions(ctx, dec, dirs, packageName)
if err != nil {
return nil, nil, err
}
@ -247,7 +251,7 @@ func (b *Builder) BuildPackage(ctx context.Context) ([]string, []string, error)
pkgFormat := getPkgFormat(b.opts.Manager) // Получаем формат пакета
pkgInfo, err := buildPkgMetadata(ctx, vars, dirs, pkgFormat, b.info, append(repoDeps, builtNames...), funcOut.Contents) // Собираем метаданные пакета
pkgInfo, err := b.buildPkgMetadata(ctx, vars, dirs, pkgFormat, append(repoDeps, builtNames...), funcOut.Contents) // Собираем метаданные пакета
if err != nil {
return nil, nil, err
}
@ -366,6 +370,7 @@ func (b *Builder) executeFirstPass(
}
vars := preVars.ToBuildVars()
vars.Name = pkgName
vars.Base = pkgs.BasePkgName
varsOfPackages = append(varsOfPackages, &vars)
}
@ -678,8 +683,8 @@ func (b *Builder) executePackageFunctions(
var filesFuncName string
if packageName == "" {
filesFuncName = "files"
packageFuncName = "package"
filesFuncName = "files"
} else {
packageFuncName = fmt.Sprintf("package_%s", packageName)
filesFuncName = fmt.Sprintf("files_%s", packageName)
@ -795,3 +800,109 @@ func (b *Builder) InstallALRPackages(ctx context.Context, pkgs []db.Package, opt
}
}
}
// Функция buildPkgMetadata создает метаданные для пакета, который будет собран.
func (b *Builder) buildPkgMetadata(
ctx context.Context,
vars *types.BuildVars,
dirs types.Directories,
pkgFormat string,
deps []string,
preferedContents *[]string,
) (*nfpm.Info, error) {
pkgInfo := getBasePkgInfo(vars, b.info, &b.opts)
pkgInfo.Description = vars.Description
pkgInfo.Platform = "linux"
pkgInfo.Homepage = vars.Homepage
pkgInfo.License = strings.Join(vars.Licenses, ", ")
pkgInfo.Maintainer = vars.Maintainer
pkgInfo.Overridables = nfpm.Overridables{
Conflicts: append(vars.Conflicts, vars.Name),
Replaces: vars.Replaces,
Provides: append(vars.Provides, vars.Name),
Depends: deps,
}
if pkgFormat == "apk" {
// Alpine отказывается устанавливать пакеты, которые предоставляют сами себя, поэтому удаляем такие элементы
pkgInfo.Overridables.Provides = slices.DeleteFunc(pkgInfo.Overridables.Provides, func(s string) bool {
return s == pkgInfo.Name
})
}
if vars.Epoch != 0 {
pkgInfo.Epoch = strconv.FormatUint(uint64(vars.Epoch), 10)
}
setScripts(vars, pkgInfo, dirs.ScriptDir)
if slices.Contains(vars.Architectures, "all") {
pkgInfo.Arch = "all"
}
contents, err := buildContents(vars, dirs, preferedContents)
if err != nil {
return nil, err
}
slog.Info("contents", "contents", contents)
pkgInfo.Overridables.Contents = contents
if len(vars.AutoProv) == 1 && decoder.IsTruthy(vars.AutoProv[0]) {
if pkgFormat == "rpm" {
err = rpmFindProvides(ctx, pkgInfo, dirs)
if err != nil {
return nil, err
}
} else {
slog.Info(gotext.Get("AutoProv is not implemented for this package format, so it's skipped"))
}
}
if len(vars.AutoReq) == 1 && decoder.IsTruthy(vars.AutoReq[0]) {
if pkgFormat == "rpm" {
err = rpmFindRequires(ctx, pkgInfo, dirs)
if err != nil {
return nil, err
}
} else {
slog.Info(gotext.Get("AutoReq is not implemented for this package format, so it's skipped"))
}
}
return pkgInfo, nil
}
// Функция checkForBuiltPackage пытается обнаружить ранее собранный пакет и вернуть его путь
// и true, если нашла. Если нет, возвратит "", false, nil.
func (b *Builder) checkForBuiltPackage(
vars *types.BuildVars,
pkgFormat,
baseDir string,
) (string, bool, error) {
filename, err := b.pkgFileName(vars, pkgFormat)
if err != nil {
return "", false, err
}
pkgPath := filepath.Join(baseDir, filename)
_, err = os.Stat(pkgPath)
if err != nil {
return "", false, nil
}
return pkgPath, true, nil
}
// 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 (b *Builder) pkgFileName(vars *types.BuildVars, pkgFormat string) (string, error) {
pkgInfo := getBasePkgInfo(vars, b.info, &b.opts)
packager, err := nfpm.Get(pkgFormat)
if err != nil {
return "", err
}
return packager.ConventionalFileName(pkgInfo), nil
}

@ -17,11 +17,11 @@
package build
import (
"context"
"fmt"
"io"
"log/slog"
"os"
"path/filepath"
"regexp"
"runtime"
"slices"
"strconv"
@ -33,7 +33,6 @@ import (
_ "github.com/goreleaser/nfpm/v2/arch"
_ "github.com/goreleaser/nfpm/v2/deb"
_ "github.com/goreleaser/nfpm/v2/rpm"
"github.com/leonelquinteros/gotext"
"mvdan.cc/sh/v3/syntax"
"github.com/goreleaser/nfpm/v2"
@ -42,7 +41,6 @@ import (
"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"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/decoder"
"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"
@ -77,77 +75,6 @@ func prepareDirs(dirs types.Directories) error {
return os.MkdirAll(dirs.PkgDir, 0o755) // Создаем директорию для пакетов
}
// Функция buildPkgMetadata создает метаданные для пакета, который будет собран.
func buildPkgMetadata(
ctx context.Context,
vars *types.BuildVars,
dirs types.Directories,
pkgFormat string,
info *distro.OSRelease,
deps []string,
preferedContents *[]string,
) (*nfpm.Info, error) {
pkgInfo := getBasePkgInfo(vars, info)
pkgInfo.Description = vars.Description
pkgInfo.Platform = "linux"
pkgInfo.Homepage = vars.Homepage
pkgInfo.License = strings.Join(vars.Licenses, ", ")
pkgInfo.Maintainer = vars.Maintainer
pkgInfo.Overridables = nfpm.Overridables{
Conflicts: vars.Conflicts,
Replaces: vars.Replaces,
Provides: vars.Provides,
Depends: deps,
}
if pkgFormat == "apk" {
// Alpine отказывается устанавливать пакеты, которые предоставляют сами себя, поэтому удаляем такие элементы
pkgInfo.Overridables.Provides = slices.DeleteFunc(pkgInfo.Overridables.Provides, func(s string) bool {
return s == pkgInfo.Name
})
}
if vars.Epoch != 0 {
pkgInfo.Epoch = strconv.FormatUint(uint64(vars.Epoch), 10)
}
setScripts(vars, pkgInfo, dirs.ScriptDir)
if slices.Contains(vars.Architectures, "all") {
pkgInfo.Arch = "all"
}
contents, err := buildContents(vars, dirs, preferedContents)
if err != nil {
return nil, err
}
pkgInfo.Overridables.Contents = contents
if len(vars.AutoProv) == 1 && decoder.IsTruthy(vars.AutoProv[0]) {
if pkgFormat == "rpm" {
err = rpmFindProvides(ctx, pkgInfo, dirs)
if err != nil {
return nil, err
}
} else {
slog.Info(gotext.Get("AutoProv is not implemented for this package format, so it's skipped"))
}
}
if len(vars.AutoReq) == 1 && decoder.IsTruthy(vars.AutoReq[0]) {
if pkgFormat == "rpm" {
err = rpmFindRequires(ctx, pkgInfo, dirs)
if err != nil {
return nil, err
}
} else {
slog.Info(gotext.Get("AutoReq is not implemented for this package format, so it's skipped"))
}
}
return pkgInfo, nil
}
// Функция buildContents создает секцию содержимого пакета, которая содержит файлы,
// которые будут включены в конечный пакет.
func buildContents(vars *types.BuildVars, dirs types.Directories, preferedContents *[]string) ([]*files.Content, error) {
@ -244,33 +171,11 @@ func buildContents(vars *types.BuildVars, dirs types.Directories, preferedConten
return contents, nil
}
// Функция checkForBuiltPackage пытается обнаружить ранее собранный пакет и вернуть его путь
// и true, если нашла. Если нет, возвратит "", false, nil.
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
}
var RegexpALRPackageName = regexp.MustCompile(`^(?P<package>[^+]+)\+alr-(?P<repo>.+)$`)
pkgPath := filepath.Join(baseDir, filename)
_, err = os.Stat(pkgPath)
if err != nil {
return "", false, nil
}
return pkgPath, true, nil
}
func getBasePkgInfo(vars *types.BuildVars, info *distro.OSRelease) *nfpm.Info {
func getBasePkgInfo(vars *types.BuildVars, info *distro.OSRelease, opts *types.BuildOpts) *nfpm.Info {
return &nfpm.Info{
Name: vars.Name,
Name: fmt.Sprintf("%s+alr-%s", vars.Name, opts.Repository),
Arch: cpu.Arch(),
Version: vars.Version,
Release: overrides.ReleasePlatformSpecific(vars.Release, info),
@ -278,19 +183,6 @@ func getBasePkgInfo(vars *types.BuildVars, info *distro.OSRelease) *nfpm.Info {
}
}
// 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, info *distro.OSRelease) (string, error) {
pkgInfo := getBasePkgInfo(vars, info)
packager, err := nfpm.Get(pkgFormat)
if err != nil {
return "", err
}
return packager.ConventionalFileName(pkgInfo), nil
}
// Функция getPkgFormat возвращает формат пакета из менеджера пакетов,
// или ALR_PKG_FORMAT, если он установлен.
func getPkgFormat(mgr manager.Manager) string {

@ -83,7 +83,7 @@ func AddRepoCmd() *cli.Command {
os.Exit(1)
}
err = toml.NewEncoder(cfgFl).Encode(cfg)
err = cfg.Save(cfgFl)
if err != nil {
slog.Error(gotext.Get("Error encoding config"), "err", err)
os.Exit(1)

@ -29,7 +29,6 @@ import (
"github.com/urfave/cli/v2"
"go.elara.ws/vercmp"
"golang.org/x/exp/maps"
"golang.org/x/exp/slices"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
database "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
@ -39,6 +38,7 @@ import (
"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"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/search"
)
func UpgradeCmd() *cli.Command {
@ -85,7 +85,7 @@ func UpgradeCmd() *cli.Command {
}
}
updates, err := checkForUpdates(ctx, mgr, cfg, rs, info)
updates, err := checkForUpdates(ctx, mgr, cfg, db, rs, info)
if err != nil {
slog.Error(gotext.Get("Error checking for updates"), "err", err)
os.Exit(1)
@ -121,6 +121,7 @@ func checkForUpdates(
ctx context.Context,
mgr manager.Manager,
cfg *config.ALRConfig,
db *database.Database,
rs *repos.Repos,
info *distro.OSRelease,
) ([]database.Package, error) {
@ -130,42 +131,47 @@ func checkForUpdates(
}
pkgNames := maps.Keys(installed)
found, _, err := rs.FindPkgs(ctx, pkgNames)
if err != nil {
return nil, err
}
s := search.New(db)
var out []database.Package
for pkgName, pkgs := range found {
if slices.Contains(cfg.IgnorePkgUpdates(ctx), pkgName) {
continue
for _, pkgName := range pkgNames {
matches := build.RegexpALRPackageName.FindStringSubmatch(pkgName)
if matches != nil {
packageName := matches[build.RegexpALRPackageName.SubexpIndex("package")]
repoName := matches[build.RegexpALRPackageName.SubexpIndex("repo")]
pkgs, err := s.Search(
ctx,
search.NewSearchOptions().
WithName(packageName).
WithRepository(repoName).
Build(),
)
if err != nil {
return nil, err
}
pkg := pkgs[0]
repoVer := pkg.Version
releaseStr := overrides.ReleasePlatformSpecific(pkg.Release, info)
if pkg.Release != 0 && pkg.Epoch == 0 {
repoVer = fmt.Sprintf("%s-%s", pkg.Version, releaseStr)
} else if pkg.Release != 0 && pkg.Epoch != 0 {
repoVer = fmt.Sprintf("%d:%s-%s", pkg.Epoch, pkg.Version, releaseStr)
}
c := vercmp.Compare(repoVer, installed[pkgName])
if c == 0 || c == -1 {
continue
} else if c == 1 {
out = append(out, pkg)
}
}
if len(pkgs) > 1 {
// Puts the element with the highest version first
slices.SortFunc(pkgs, func(a, b database.Package) int {
return vercmp.Compare(a.Version, b.Version)
})
}
// First element is the package we want to install
pkg := pkgs[0]
repoVer := pkg.Version
releaseStr := overrides.ReleasePlatformSpecific(pkg.Release, info)
if pkg.Release != 0 && pkg.Epoch == 0 {
repoVer = fmt.Sprintf("%s-%s", pkg.Version, releaseStr)
} else if pkg.Release != 0 && pkg.Epoch != 0 {
repoVer = fmt.Sprintf("%d:%s-%s", pkg.Epoch, pkg.Version, releaseStr)
}
c := vercmp.Compare(repoVer, installed[pkgName])
if c == 0 || c == -1 {
continue
} else if c == 1 {
out = append(out, pkg)
}
}
return out, nil
}