diff --git a/build.go b/build.go index 6b372bd..120d650 100644 --- a/build.go +++ b/build.go @@ -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"), diff --git a/internal/translations/default.pot b/internal/translations/default.pot index 8e2ee3c..0c72ed8 100644 --- a/internal/translations/default.pot +++ b/internal/translations/default.pot @@ -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 "" @@ -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 "" diff --git a/internal/translations/po/ru/default.po b/internal/translations/po/ru/default.po index 4420300..d446585 100644 --- a/internal/translations/po/ru/default.po +++ b/internal/translations/po/ru/default.po @@ -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 "Ошибка при перемещении пакета" @@ -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 "Скачивание репозитория" diff --git a/internal/types/build.go b/internal/types/build.go index a975e92..6b5c6c9 100644 --- a/internal/types/build.go +++ b/internal/types/build.go @@ -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 { diff --git a/pkg/build/build.go b/pkg/build/build.go index 38d91a5..35ff75e 100644 --- a/pkg/build/build.go +++ b/pkg/build/build.go @@ -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 +} diff --git a/pkg/build/utils.go b/pkg/build/utils.go index 3b3ba49..15db132 100644 --- a/pkg/build/utils.go +++ b/pkg/build/utils.go @@ -17,9 +17,8 @@ package build import ( - "context" + "fmt" "io" - "log/slog" "os" "path/filepath" "runtime" @@ -33,7 +32,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 +40,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 +74,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 +170,9 @@ 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 - } - - 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 +180,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 {