diff --git a/assets/coverage-badge.svg b/assets/coverage-badge.svg
index fc517f1..42e7827 100644
--- a/assets/coverage-badge.svg
+++ b/assets/coverage-badge.svg
@@ -11,7 +11,7 @@
coverage
coverage
- 16.5%
- 16.5%
+ 17.6%
+ 17.6%
diff --git a/e2e-tests/group_and_summary_field_test.go b/e2e-tests/group_and_summary_field_test.go
index ec9fb05..93a198c 100644
--- a/e2e-tests/group_and_summary_field_test.go
+++ b/e2e-tests/group_and_summary_field_test.go
@@ -31,8 +31,8 @@ func TestE2EGroupAndSummaryField(t *testing.T) {
RPM_SYSTEMS,
func(t *testing.T, r e2e.Runnable) {
defaultPrepare(t, r)
- execShouldNoError(t, r, "sh", "-c", "alr search --name test-group-and-summary --format \"{{.Group}}\" | grep ^System/Base$")
- execShouldNoError(t, r, "sh", "-c", "alr search --name test-group-and-summary --format \"{{.Summary}}\" | grep \"^Custom summary$\"")
+ execShouldNoError(t, r, "sh", "-c", "alr search --name test-group-and-summary --format \"{{.Group.Resolved}}\" | grep ^System/Base$")
+ execShouldNoError(t, r, "sh", "-c", "alr search --name test-group-and-summary --format \"{{.Summary.Resolved}}\" | grep \"^Custom summary$\"")
},
)
}
diff --git a/info.go b/info.go
index 48b4e95..5652eb5 100644
--- a/info.go
+++ b/info.go
@@ -32,6 +32,7 @@ import (
appbuilder "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils/app_builder"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/overrides"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/utils"
+ "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
)
@@ -88,6 +89,7 @@ func InfoCmd() *cli.Command {
New(ctx).
WithConfig().
WithDB().
+ WithDistroInfo().
WithRepos().
Build()
if err != nil {
@@ -136,7 +138,8 @@ func InfoCmd() *cli.Command {
for _, pkg := range pkgs {
if !all {
- err = yaml.NewEncoder(os.Stdout).Encode(overrides.ResolvePackage(&pkg, names))
+ alrsh.ResolvePackage(&pkg, names)
+ err = yaml.NewEncoder(os.Stdout).Encode(pkg)
if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error encoding script variables"), err)
}
diff --git a/internal/build/build.go b/internal/build/build.go
index b47a6e1..ff7a2d2 100644
--- a/internal/build/build.go
+++ b/internal/build/build.go
@@ -24,13 +24,13 @@ import (
"context"
"encoding/gob"
"errors"
+ "fmt"
"log/slog"
"github.com/leonelquinteros/gotext"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
- "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/manager"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
@@ -158,7 +158,7 @@ func GetBuiltName(deps []*BuiltDep) []string {
}
type PackageFinder interface {
- FindPkgs(ctx context.Context, pkgs []string) (map[string][]db.Package, []string, error)
+ FindPkgs(ctx context.Context, pkgs []string) (map[string][]alrsh.Package, []string, error)
}
type Config interface {
@@ -173,12 +173,12 @@ type FunctionsOutput struct {
// EXECUTORS
type ScriptResolverExecutor interface {
- ResolveScript(ctx context.Context, pkg *db.Package) *ScriptInfo
+ ResolveScript(ctx context.Context, pkg *alrsh.Package) *ScriptInfo
}
type ScriptExecutor interface {
- ReadScript(ctx context.Context, scriptPath string) (*alrsh.ALRSh, error)
- ExecuteFirstPass(ctx context.Context, input *BuildInput, sf *alrsh.ALRSh) (string, []*types.BuildVars, error)
+ ReadScript(ctx context.Context, scriptPath string) (*alrsh.ScriptFile, error)
+ ExecuteFirstPass(ctx context.Context, input *BuildInput, sf *alrsh.ScriptFile) (string, []*alrsh.Package, error)
PrepareDirs(
ctx context.Context,
input *BuildInput,
@@ -187,8 +187,8 @@ type ScriptExecutor interface {
ExecuteSecondPass(
ctx context.Context,
input *BuildInput,
- sf *alrsh.ALRSh,
- varsOfPackages []*types.BuildVars,
+ sf *alrsh.ScriptFile,
+ varsOfPackages []*alrsh.Package,
repoDeps []string,
builtDeps []*BuiltDep,
basePkg string,
@@ -196,18 +196,18 @@ type ScriptExecutor interface {
}
type CacheExecutor interface {
- CheckForBuiltPackage(ctx context.Context, input *BuildInput, vars *types.BuildVars) (string, bool, error)
+ CheckForBuiltPackage(ctx context.Context, input *BuildInput, vars *alrsh.Package) (string, bool, error)
}
type ScriptViewerExecutor interface {
- ViewScript(ctx context.Context, input *BuildInput, sf *alrsh.ALRSh, basePkg string) error
+ ViewScript(ctx context.Context, input *BuildInput, sf *alrsh.ScriptFile, basePkg string) error
}
type CheckerExecutor interface {
PerformChecks(
ctx context.Context,
input *BuildInput,
- vars *types.BuildVars,
+ vars *alrsh.Package,
) (bool, error)
}
@@ -285,7 +285,7 @@ func (b *BuildArgs) PkgFormat() string {
type BuildPackageFromDbArgs struct {
BuildArgs
- Package *db.Package
+ Package *alrsh.Package
Packages []string
}
@@ -334,19 +334,19 @@ func (b *Builder) BuildPackage(
slog.Debug("ReadScript")
sf, err := b.scriptExecutor.ReadScript(ctx, scriptPath)
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("failed reading script: %w", err)
}
slog.Debug("ExecuteFirstPass")
basePkg, varsOfPackages, err := b.scriptExecutor.ExecuteFirstPass(ctx, input, sf)
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("failed ExecuteFirstPass: %w", err)
}
var builtDeps []*BuiltDep
if !input.opts.Clean {
- var remainingVars []*types.BuildVars
+ var remainingVars []*alrsh.Package
for _, vars := range varsOfPackages {
builtPkgPath, ok, err := b.cacheExecutor.CheckForBuiltPackage(ctx, input, vars)
if err != nil {
@@ -367,6 +367,7 @@ func (b *Builder) BuildPackage(
}
slog.Debug("ViewScript")
+ slog.Debug("", "varsOfPackages", varsOfPackages)
err = b.scriptViewerExecutor.ViewScript(ctx, input, sf, basePkg)
if err != nil {
return nil, err
@@ -390,11 +391,11 @@ func (b *Builder) BuildPackage(
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 = append(buildDepends, vars.BuildDepends.Resolved()...)
+ optDepends = append(optDepends, vars.OptDepends.Resolved()...)
+ depends = append(depends, vars.Depends.Resolved()...)
+ sources = append(sources, vars.Sources.Resolved()...)
+ checksums = append(checksums, vars.Checksums.Resolved()...)
}
buildDepends = removeDuplicates(buildDepends)
optDepends = removeDuplicates(optDepends)
@@ -481,7 +482,7 @@ func (b *Builder) BuildPackage(
type InstallPkgsArgs struct {
BuildArgs
- AlrPkgs []db.Package
+ AlrPkgs []alrsh.Package
NativePkgs []string
}
@@ -492,7 +493,7 @@ func (b *Builder) InstallALRPackages(
BuildOptsProvider
PkgFormatProvider
},
- alrPkgs []db.Package,
+ alrPkgs []alrsh.Package,
) error {
for _, pkg := range alrPkgs {
res, err := b.BuildPackageFromDb(
@@ -539,7 +540,7 @@ func (b *Builder) BuildALRDeps(
found, notFound, err := b.repos.FindPkgs(ctx, depends) // Поиск зависимостей
if err != nil {
- return nil, nil, err
+ return nil, nil, fmt.Errorf("failed FindPkgs: %w", err)
}
repoDeps = notFound
@@ -551,7 +552,7 @@ func (b *Builder) BuildALRDeps(
input.BuildOpts().Interactive,
)
type item struct {
- pkg *db.Package
+ pkg *alrsh.Package
packages []string
}
pkgsMap := make(map[string]*item)
@@ -586,7 +587,7 @@ func (b *Builder) BuildALRDeps(
},
)
if err != nil {
- return nil, nil, err
+ return nil, nil, fmt.Errorf("failed build package from db: %w", err)
}
buildDeps = append(buildDeps, res...)
diff --git a/internal/build/cache.go b/internal/build/cache.go
index 915c0da..2453090 100644
--- a/internal/build/cache.go
+++ b/internal/build/cache.go
@@ -23,7 +23,7 @@ import (
"github.com/goreleaser/nfpm/v2"
- "gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
+ "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
)
type Cache struct {
@@ -33,7 +33,7 @@ type Cache struct {
func (c *Cache) CheckForBuiltPackage(
ctx context.Context,
input *BuildInput,
- vars *types.BuildVars,
+ vars *alrsh.Package,
) (string, bool, error) {
filename, err := pkgFileName(input, vars)
if err != nil {
@@ -56,7 +56,7 @@ func pkgFileName(
PkgFormatProvider
RepositoryProvider
},
- vars *types.BuildVars,
+ vars *alrsh.Package,
) (string, error) {
pkgInfo := getBasePkgInfo(vars, input)
diff --git a/internal/build/checker.go b/internal/build/checker.go
index 748d717..94cdc3f 100644
--- a/internal/build/checker.go
+++ b/internal/build/checker.go
@@ -25,7 +25,7 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cpu"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/manager"
- "gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
+ "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
)
type Checker struct {
@@ -35,7 +35,7 @@ type Checker struct {
func (c *Checker) PerformChecks(
ctx context.Context,
input *BuildInput,
- vars *types.BuildVars,
+ vars *alrsh.Package,
) (bool, error) {
if !cpu.IsCompatibleWith(cpu.Arch(), vars.Architectures) { // Проверяем совместимость архитектуры
cont, err := cliutils.YesNoPrompt(
diff --git a/internal/build/safe_script_executor.go b/internal/build/safe_script_executor.go
index 461bf81..3342e7b 100644
--- a/internal/build/safe_script_executor.go
+++ b/internal/build/safe_script_executor.go
@@ -29,7 +29,6 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/logger"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
- "gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
)
var HandshakeConfig = plugin.HandshakeConfig{
@@ -51,13 +50,13 @@ type ScriptExecutorRPCServer struct {
// ReadScript
//
-func (s *ScriptExecutorRPC) ReadScript(ctx context.Context, scriptPath string) (*alrsh.ALRSh, error) {
- var resp *alrsh.ALRSh
+func (s *ScriptExecutorRPC) ReadScript(ctx context.Context, scriptPath string) (*alrsh.ScriptFile, error) {
+ var resp *alrsh.ScriptFile
err := s.client.Call("Plugin.ReadScript", scriptPath, &resp)
return resp, err
}
-func (s *ScriptExecutorRPCServer) ReadScript(scriptPath string, resp *alrsh.ALRSh) error {
+func (s *ScriptExecutorRPCServer) ReadScript(scriptPath string, resp *alrsh.ScriptFile) error {
file, err := s.Impl.ReadScript(context.Background(), scriptPath)
if err != nil {
return err
@@ -73,15 +72,15 @@ func (s *ScriptExecutorRPCServer) ReadScript(scriptPath string, resp *alrsh.ALRS
type ExecuteFirstPassArgs struct {
Input *BuildInput
- Sf *alrsh.ALRSh
+ Sf *alrsh.ScriptFile
}
type ExecuteFirstPassResp struct {
BasePkg string
- VarsOfPackages []*types.BuildVars
+ VarsOfPackages []*alrsh.Package
}
-func (s *ScriptExecutorRPC) ExecuteFirstPass(ctx context.Context, input *BuildInput, sf *alrsh.ALRSh) (string, []*types.BuildVars, error) {
+func (s *ScriptExecutorRPC) ExecuteFirstPass(ctx context.Context, input *BuildInput, sf *alrsh.ScriptFile) (string, []*alrsh.Package, error) {
var resp *ExecuteFirstPassResp
err := s.client.Call("Plugin.ExecuteFirstPass", &ExecuteFirstPassArgs{
Input: input,
@@ -149,8 +148,8 @@ func (s *ScriptExecutorRPCServer) PrepareDirs(args *PrepareDirsArgs, reply *stru
type ExecuteSecondPassArgs struct {
Input *BuildInput
- Sf *alrsh.ALRSh
- VarsOfPackages []*types.BuildVars
+ Sf *alrsh.ScriptFile
+ VarsOfPackages []*alrsh.Package
RepoDeps []string
BuiltDeps []*BuiltDep
BasePkg string
@@ -159,8 +158,8 @@ type ExecuteSecondPassArgs struct {
func (s *ScriptExecutorRPC) ExecuteSecondPass(
ctx context.Context,
input *BuildInput,
- sf *alrsh.ALRSh,
- varsOfPackages []*types.BuildVars,
+ sf *alrsh.ScriptFile,
+ varsOfPackages []*alrsh.Package,
repoDeps []string,
builtDeps []*BuiltDep,
basePkg string,
diff --git a/internal/build/script_executor.go b/internal/build/script_executor.go
index 01020a9..c67edfd 100644
--- a/internal/build/script_executor.go
+++ b/internal/build/script_executor.go
@@ -53,11 +53,11 @@ func NewLocalScriptExecutor(cfg Config) *LocalScriptExecutor {
}
}
-func (e *LocalScriptExecutor) ReadScript(ctx context.Context, scriptPath string) (*alrsh.ALRSh, error) {
+func (e *LocalScriptExecutor) ReadScript(ctx context.Context, scriptPath string) (*alrsh.ScriptFile, error) {
return alrsh.ReadFromLocal(scriptPath)
}
-func (e *LocalScriptExecutor) ExecuteFirstPass(ctx context.Context, input *BuildInput, sf *alrsh.ALRSh) (string, []*types.BuildVars, error) {
+func (e *LocalScriptExecutor) ExecuteFirstPass(ctx context.Context, input *BuildInput, sf *alrsh.ScriptFile) (string, []*alrsh.Package, error) {
return sf.ParseBuildVars(ctx, input.info, input.packages)
}
@@ -86,8 +86,8 @@ func (e *LocalScriptExecutor) PrepareDirs(
func (e *LocalScriptExecutor) ExecuteSecondPass(
ctx context.Context,
input *BuildInput,
- sf *alrsh.ALRSh,
- varsOfPackages []*types.BuildVars,
+ sf *alrsh.ScriptFile,
+ varsOfPackages []*alrsh.Package,
repoDeps []string,
builtDeps []*BuiltDep,
basePkg string,
@@ -126,7 +126,7 @@ func (e *LocalScriptExecutor) ExecuteSecondPass(
for _, vars := range varsOfPackages {
packageName := ""
- if vars.Base != "" {
+ if vars.BasePkgName != "" {
packageName = vars.Name
}
@@ -194,24 +194,25 @@ func buildPkgMetadata(
PkgFormatProvider
RepositoryProvider
},
- vars *types.BuildVars,
+ vars *alrsh.Package,
dirs types.Directories,
deps []string,
preferedContents *[]string,
) (*nfpm.Info, error) {
pkgInfo := getBasePkgInfo(vars, input)
- pkgInfo.Description = vars.Description
+ slog.Warn("vars.Description", "vars.Description", vars.Description, "vars.Description.Resolved", vars.Description.Resolved())
+ pkgInfo.Description = vars.Description.Resolved()
pkgInfo.Platform = "linux"
- pkgInfo.Homepage = vars.Homepage
+ pkgInfo.Homepage = vars.Homepage.Resolved()
pkgInfo.License = strings.Join(vars.Licenses, ", ")
- pkgInfo.Maintainer = vars.Maintainer
+ pkgInfo.Maintainer = vars.Maintainer.Resolved()
pkgInfo.Overridables = nfpm.Overridables{
Conflicts: append(vars.Conflicts, vars.Name),
Replaces: vars.Replaces,
Provides: append(vars.Provides, vars.Name),
Depends: deps,
}
- pkgInfo.Section = vars.Group
+ pkgInfo.Section = vars.Group.Resolved()
pkgFormat := input.PkgFormat()
info := input.OSRelease()
@@ -224,12 +225,12 @@ func buildPkgMetadata(
}
if pkgFormat == "rpm" {
- pkgInfo.RPM.Group = vars.Group
+ pkgInfo.RPM.Group = vars.Group.Resolved()
- if vars.Summary != "" {
- pkgInfo.RPM.Summary = vars.Summary
+ if vars.Summary.Resolved() != "" {
+ pkgInfo.RPM.Summary = vars.Summary.Resolved()
} else {
- lines := strings.SplitN(vars.Description, "\n", 2)
+ lines := strings.SplitN(vars.Description.Resolved(), "\n", 2)
pkgInfo.RPM.Summary = lines[0]
}
}
@@ -250,17 +251,17 @@ func buildPkgMetadata(
}
pkgInfo.Overridables.Contents = contents
- if len(vars.AutoProv) == 1 && decoder.IsTruthy(vars.AutoProv[0]) {
+ if len(vars.AutoProv.Resolved()) == 1 && decoder.IsTruthy(vars.AutoProv.Resolved()[0]) {
f := finddeps.New(info, pkgFormat)
- err = f.FindProvides(ctx, pkgInfo, dirs, vars.AutoProvSkipList)
+ err = f.FindProvides(ctx, pkgInfo, dirs, vars.AutoProvSkipList.Resolved())
if err != nil {
return nil, err
}
}
- if len(vars.AutoReq) == 1 && decoder.IsTruthy(vars.AutoReq[0]) {
+ if len(vars.AutoReq.Resolved()) == 1 && decoder.IsTruthy(vars.AutoReq.Resolved()[0]) {
f := finddeps.New(info, pkgFormat)
- err = f.FindRequires(ctx, pkgInfo, dirs, vars.AutoReqSkipList)
+ err = f.FindRequires(ctx, pkgInfo, dirs, vars.AutoReqSkipList.Resolved())
if err != nil {
return nil, err
}
diff --git a/internal/build/script_resolver.go b/internal/build/script_resolver.go
index 06edcfb..70bf763 100644
--- a/internal/build/script_resolver.go
+++ b/internal/build/script_resolver.go
@@ -20,7 +20,7 @@ import (
"context"
"path/filepath"
- "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
+ "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
)
type ScriptResolver struct {
@@ -34,7 +34,7 @@ type ScriptInfo struct {
func (s *ScriptResolver) ResolveScript(
ctx context.Context,
- pkg *db.Package,
+ pkg *alrsh.Package,
) *ScriptInfo {
var repository, script string
diff --git a/internal/build/script_view.go b/internal/build/script_view.go
index 52f47c3..e72cdfa 100644
--- a/internal/build/script_view.go
+++ b/internal/build/script_view.go
@@ -34,7 +34,7 @@ type ScriptViewer struct {
func (s *ScriptViewer) ViewScript(
ctx context.Context,
input *BuildInput,
- a *alrsh.ALRSh,
+ a *alrsh.ScriptFile,
basePkg string,
) error {
return cliutils.PromptViewScript(
diff --git a/internal/build/utils.go b/internal/build/utils.go
index fd7569a..1ef2f9d 100644
--- a/internal/build/utils.go
+++ b/internal/build/utils.go
@@ -40,6 +40,7 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cpu"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/manager"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/overrides"
+ "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
)
@@ -59,7 +60,7 @@ func prepareDirs(dirs types.Directories) error {
// Функция buildContents создает секцию содержимого пакета, которая содержит файлы,
// которые будут включены в конечный пакет.
-func buildContents(vars *types.BuildVars, dirs types.Directories, preferedContents *[]string) ([]*files.Content, error) {
+func buildContents(vars *alrsh.Package, dirs types.Directories, preferedContents *[]string) ([]*files.Content, error) {
contents := []*files.Content{}
processPath := func(path, trimmed string, prefered bool) error {
@@ -122,7 +123,7 @@ func buildContents(vars *types.BuildVars, dirs types.Directories, preferedConten
},
}
- if slices.Contains(vars.Backup, trimmed) {
+ if slices.Contains(vars.Backup.Resolved(), trimmed) {
fileContent.Type = "config|noreplace"
}
@@ -155,7 +156,7 @@ func buildContents(vars *types.BuildVars, dirs types.Directories, preferedConten
var RegexpALRPackageName = regexp.MustCompile(`^(?P[^+]+)\+alr-(?P.+)$`)
-func getBasePkgInfo(vars *types.BuildVars, input interface {
+func getBasePkgInfo(vars *alrsh.Package, input interface {
RepositoryProvider
OsInfoProvider
},
@@ -211,39 +212,39 @@ func createBuildEnvVars(info *distro.OSRelease, dirs types.Directories) []string
}
// Функция setScripts добавляет скрипты-перехватчики к метаданным пакета.
-func setScripts(vars *types.BuildVars, info *nfpm.Info, scriptDir string) {
- if vars.Scripts.PreInstall != "" {
- info.Scripts.PreInstall = filepath.Join(scriptDir, vars.Scripts.PreInstall)
+func setScripts(vars *alrsh.Package, info *nfpm.Info, scriptDir string) {
+ if vars.Scripts.Resolved().PreInstall != "" {
+ info.Scripts.PreInstall = filepath.Join(scriptDir, vars.Scripts.Resolved().PreInstall)
}
- if vars.Scripts.PostInstall != "" {
- info.Scripts.PostInstall = filepath.Join(scriptDir, vars.Scripts.PostInstall)
+ if vars.Scripts.Resolved().PostInstall != "" {
+ info.Scripts.PostInstall = filepath.Join(scriptDir, vars.Scripts.Resolved().PostInstall)
}
- if vars.Scripts.PreRemove != "" {
- info.Scripts.PreRemove = filepath.Join(scriptDir, vars.Scripts.PreRemove)
+ if vars.Scripts.Resolved().PreRemove != "" {
+ info.Scripts.PreRemove = filepath.Join(scriptDir, vars.Scripts.Resolved().PreRemove)
}
- if vars.Scripts.PostRemove != "" {
- info.Scripts.PostRemove = filepath.Join(scriptDir, vars.Scripts.PostRemove)
+ if vars.Scripts.Resolved().PostRemove != "" {
+ info.Scripts.PostRemove = filepath.Join(scriptDir, vars.Scripts.Resolved().PostRemove)
}
- if vars.Scripts.PreUpgrade != "" {
- info.ArchLinux.Scripts.PreUpgrade = filepath.Join(scriptDir, vars.Scripts.PreUpgrade)
- info.APK.Scripts.PreUpgrade = filepath.Join(scriptDir, vars.Scripts.PreUpgrade)
+ if vars.Scripts.Resolved().PreUpgrade != "" {
+ info.ArchLinux.Scripts.PreUpgrade = filepath.Join(scriptDir, vars.Scripts.Resolved().PreUpgrade)
+ info.APK.Scripts.PreUpgrade = filepath.Join(scriptDir, vars.Scripts.Resolved().PreUpgrade)
}
- if vars.Scripts.PostUpgrade != "" {
- info.ArchLinux.Scripts.PostUpgrade = filepath.Join(scriptDir, vars.Scripts.PostUpgrade)
- info.APK.Scripts.PostUpgrade = filepath.Join(scriptDir, vars.Scripts.PostUpgrade)
+ if vars.Scripts.Resolved().PostUpgrade != "" {
+ info.ArchLinux.Scripts.PostUpgrade = filepath.Join(scriptDir, vars.Scripts.Resolved().PostUpgrade)
+ info.APK.Scripts.PostUpgrade = filepath.Join(scriptDir, vars.Scripts.Resolved().PostUpgrade)
}
- if vars.Scripts.PreTrans != "" {
- info.RPM.Scripts.PreTrans = filepath.Join(scriptDir, vars.Scripts.PreTrans)
+ if vars.Scripts.Resolved().PreTrans != "" {
+ info.RPM.Scripts.PreTrans = filepath.Join(scriptDir, vars.Scripts.Resolved().PreTrans)
}
- if vars.Scripts.PostTrans != "" {
- info.RPM.Scripts.PostTrans = filepath.Join(scriptDir, vars.Scripts.PostTrans)
+ if vars.Scripts.Resolved().PostTrans != "" {
+ info.RPM.Scripts.PostTrans = filepath.Join(scriptDir, vars.Scripts.Resolved().PostTrans)
}
}
diff --git a/internal/cliutils/app_builder/builder.go b/internal/cliutils/app_builder/builder.go
index 0d8fe40..a946a12 100644
--- a/internal/cliutils/app_builder/builder.go
+++ b/internal/cliutils/app_builder/builder.go
@@ -123,8 +123,15 @@ func (b *AppBuilder) withRepos(enablePull, forcePull bool) *AppBuilder {
cfg := b.deps.Cfg
db := b.deps.DB
- if cfg == nil || db == nil {
- b.err = errors.New("config and db are required before initializing repos")
+ info := b.deps.Info
+
+ if info == nil {
+ b.WithDistroInfo()
+ info = b.deps.Info
+ }
+
+ if cfg == nil || db == nil || info == nil {
+ b.err = errors.New("config, db and info are required before initializing repos")
return b
}
diff --git a/internal/cliutils/prompt.go b/internal/cliutils/prompt.go
index af04fa0..bc07c39 100644
--- a/internal/cliutils/prompt.go
+++ b/internal/cliutils/prompt.go
@@ -28,8 +28,8 @@ import (
"github.com/AlecAivazis/survey/v2"
"github.com/leonelquinteros/gotext"
- "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/pager"
+ "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
)
// YesNoPrompt asks the user a yes or no question, using def as the default answer
@@ -102,8 +102,8 @@ func ShowScript(path, name, style string) error {
// FlattenPkgs attempts to flatten the a map of slices of packages into a single slice
// of packages by prompting the user if multiple packages match.
-func FlattenPkgs(ctx context.Context, found map[string][]db.Package, verb string, interactive bool) []db.Package {
- var outPkgs []db.Package
+func FlattenPkgs(ctx context.Context, found map[string][]alrsh.Package, verb string, interactive bool) []alrsh.Package {
+ var outPkgs []alrsh.Package
for _, pkgs := range found {
if len(pkgs) > 1 && interactive {
choice, err := PkgPrompt(ctx, pkgs, verb, interactive)
@@ -120,7 +120,7 @@ func FlattenPkgs(ctx context.Context, found map[string][]db.Package, verb string
}
// PkgPrompt asks the user to choose between multiple packages.
-func PkgPrompt(ctx context.Context, options []db.Package, verb string, interactive bool) (db.Package, error) {
+func PkgPrompt(ctx context.Context, options []alrsh.Package, verb string, interactive bool) (alrsh.Package, error) {
if !interactive {
return options[0], nil
}
@@ -138,7 +138,7 @@ func PkgPrompt(ctx context.Context, options []db.Package, verb string, interacti
var choice int
err := survey.AskOne(prompt, &choice)
if err != nil {
- return db.Package{}, err
+ return alrsh.Package{}, err
}
return options[choice], nil
diff --git a/internal/cliutils/utils.go b/internal/cliutils/utils.go
index 010d2e0..48c4dc7 100644
--- a/internal/cliutils/utils.go
+++ b/internal/cliutils/utils.go
@@ -20,6 +20,7 @@ import (
"errors"
"fmt"
"log/slog"
+ "runtime/debug"
"github.com/leonelquinteros/gotext"
"github.com/urfave/cli/v2"
@@ -44,10 +45,12 @@ func HandleExitCoder(err error) {
slog.Error(err.Error())
}
}
+ debug.PrintStack()
cli.OsExiter(exitErr.ExitCode())
return
}
+ debug.PrintStack()
slog.Error(err.Error())
cli.OsExiter(1)
}
diff --git a/internal/db/db.go b/internal/db/db.go
index 62ebff9..ffb9298 100644
--- a/internal/db/db.go
+++ b/internal/db/db.go
@@ -28,32 +28,11 @@ import (
"xorm.io/xorm"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
+ "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
)
const CurrentVersion = 5
-type Package struct {
- BasePkgName string `sh:"basepkg_name" xorm:"notnull 'basepkg_name'"`
- Name string `sh:"name,required" xorm:"notnull unique(name_repo) 'name'"`
- Version string `sh:"version,required" xorm:"notnull 'version'"`
- Release int `sh:"release" xorm:"notnull 'release'"`
- Epoch uint `sh:"epoch" xorm:"'epoch'"`
- Summary map[string]string `xorm:"json 'summary'"`
- Description map[string]string `xorm:"json 'description'"`
- Group map[string]string `xorm:"json 'group_name'"`
- Homepage map[string]string `xorm:"json 'homepage'"`
- Maintainer map[string]string `xorm:"json 'maintainer'"`
- Architectures []string `sh:"architectures" xorm:"json 'architectures'"`
- Licenses []string `sh:"license" xorm:"json 'licenses'"`
- Provides []string `sh:"provides" xorm:"json 'provides'"`
- Conflicts []string `sh:"conflicts" xorm:"json 'conflicts'"`
- Replaces []string `sh:"replaces" xorm:"json 'replaces'"`
- Depends map[string][]string `xorm:"json 'depends'"`
- BuildDepends map[string][]string `xorm:"json 'builddepends'"`
- OptDepends map[string][]string `xorm:"json 'optdepends'"`
- Repository string `xorm:"notnull unique(name_repo) 'repository'"`
-}
-
type Version struct {
Version int `xorm:"'version'"`
}
@@ -76,6 +55,8 @@ func New(config Config) *Database {
func (d *Database) Connect() error {
dsn := d.config.GetPaths().DBPath
engine, err := xorm.NewEngine("sqlite", dsn)
+ // engine.SetLogLevel(log.LOG_DEBUG)
+ // engine.ShowSQL(true)
if err != nil {
return err
}
@@ -87,7 +68,7 @@ func (d *Database) Init(ctx context.Context) error {
if err := d.Connect(); err != nil {
return err
}
- if err := d.engine.Sync2(new(Package), new(Version)); err != nil {
+ if err := d.engine.Sync2(new(alrsh.Package), new(Version)); err != nil {
return err
}
ver, ok := d.GetVersion(ctx)
@@ -119,10 +100,10 @@ func (d *Database) addVersion(ver int) error {
}
func (d *Database) reset() error {
- return d.engine.DropTables(new(Package), new(Version))
+ return d.engine.DropTables(new(alrsh.Package), new(Version))
}
-func (d *Database) InsertPackage(ctx context.Context, pkg Package) error {
+func (d *Database) InsertPackage(ctx context.Context, pkg alrsh.Package) error {
session := d.engine.Context(ctx)
affected, err := session.Where("name = ? AND repository = ?", pkg.Name, pkg.Repository).Update(&pkg)
@@ -140,14 +121,14 @@ func (d *Database) InsertPackage(ctx context.Context, pkg Package) error {
return nil
}
-func (d *Database) GetPkgs(_ context.Context, where string, args ...any) ([]Package, error) {
- var pkgs []Package
+func (d *Database) GetPkgs(_ context.Context, where string, args ...any) ([]alrsh.Package, error) {
+ var pkgs []alrsh.Package
err := d.engine.Where(where, args...).Find(&pkgs)
return pkgs, err
}
-func (d *Database) GetPkg(where string, args ...any) (*Package, error) {
- var pkg Package
+func (d *Database) GetPkg(where string, args ...any) (*alrsh.Package, error) {
+ var pkg alrsh.Package
has, err := d.engine.Where(where, args...).Get(&pkg)
if err != nil || !has {
return nil, err
@@ -156,12 +137,12 @@ func (d *Database) GetPkg(where string, args ...any) (*Package, error) {
}
func (d *Database) DeletePkgs(_ context.Context, where string, args ...any) error {
- _, err := d.engine.Where(where, args...).Delete(&Package{})
+ _, err := d.engine.Where(where, args...).Delete(&alrsh.Package{})
return err
}
func (d *Database) IsEmpty() bool {
- count, err := d.engine.Count(new(Package))
+ count, err := d.engine.Count(new(alrsh.Package))
return err != nil || count == 0
}
diff --git a/internal/db/db_test.go b/internal/db/db_test.go
index 3621905..1962604 100644
--- a/internal/db/db_test.go
+++ b/internal/db/db_test.go
@@ -25,8 +25,11 @@ import (
"strings"
"testing"
+ "github.com/stretchr/testify/assert"
+
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
+ "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
)
type TestALRConfig struct{}
@@ -43,35 +46,38 @@ func prepareDb() *db.Database {
return database
}
-var testPkg = db.Package{
+var testPkg = alrsh.Package{
Name: "test",
Version: "0.0.1",
Release: 1,
Epoch: 2,
- Description: map[string]string{
+ Description: alrsh.OverridableFromMap(map[string]string{
"en": "Test package",
"ru": "Проверочный пакет",
- },
- Homepage: map[string]string{
+ }),
+ Homepage: alrsh.OverridableFromMap(map[string]string{
"en": "https://gitea.plemya-x.ru/xpamych/ALR",
- },
- Maintainer: map[string]string{
+ }),
+ Maintainer: alrsh.OverridableFromMap(map[string]string{
"en": "Evgeniy Khramov ",
"ru": "Евгений Храмов ",
- },
+ }),
Architectures: []string{"arm64", "amd64"},
Licenses: []string{"GPL-3.0-or-later"},
Provides: []string{"test"},
Conflicts: []string{"test"},
Replaces: []string{"test-old"},
- Depends: map[string][]string{
+ Depends: alrsh.OverridableFromMap(map[string][]string{
"": {"sudo"},
- },
- BuildDepends: map[string][]string{
+ }),
+ BuildDepends: alrsh.OverridableFromMap(map[string][]string{
"": {"golang"},
"arch": {"go"},
- },
+ }),
Repository: "default",
+ Summary: alrsh.OverridableFromMap(map[string]string{}),
+ Group: alrsh.OverridableFromMap(map[string]string{}),
+ OptDepends: alrsh.OverridableFromMap(map[string][]string{}),
}
func TestInit(t *testing.T) {
@@ -106,9 +112,7 @@ func TestInsertPackage(t *testing.T) {
t.Fatalf("Expected 1 package, got %d", len(pkgs))
}
- if !reflect.DeepEqual(testPkg, pkgs[0]) {
- t.Errorf("Expected test package to be the same as database package")
- }
+ assert.Equal(t, testPkg, pkgs[0])
}
func TestGetPkgs(t *testing.T) {
diff --git a/internal/overrides/overrides.go b/internal/overrides/overrides.go
index 8d42f8a..00bdc48 100644
--- a/internal/overrides/overrides.go
+++ b/internal/overrides/overrides.go
@@ -21,7 +21,6 @@ package overrides
import (
"fmt"
- "reflect"
"regexp"
"strings"
@@ -29,7 +28,6 @@ import (
"golang.org/x/text/language"
"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/pkg/distro"
)
@@ -150,65 +148,6 @@ func (o *Opts) WithLanguageTags(langs []string) *Opts {
return out
}
-// ResolvedPackage is a ALR package after its overrides
-// have been resolved
-type ResolvedPackage struct {
- Name string `sh:"name"`
- Version string `sh:"version"`
- Release int `sh:"release"`
- Epoch uint `sh:"epoch"`
- Group string `db:"group_name"`
- Summary string `db:"summary"`
- Description string `db:"description"`
- Homepage string `db:"homepage"`
- Maintainer string `db:"maintainer"`
- Architectures []string `sh:"architectures"`
- Licenses []string `sh:"license"`
- Provides []string `sh:"provides"`
- Conflicts []string `sh:"conflicts"`
- Replaces []string `sh:"replaces"`
- Depends []string `sh:"deps"`
- BuildDepends []string `sh:"build_deps"`
- OptDepends []string `sh:"opt_deps"`
-}
-
-func ResolvePackage(pkg *db.Package, overrides []string) *ResolvedPackage {
- out := &ResolvedPackage{}
- outVal := reflect.ValueOf(out).Elem()
- pkgVal := reflect.ValueOf(pkg).Elem()
-
- for i := 0; i < outVal.NumField(); i++ {
- fieldVal := outVal.Field(i)
- fieldType := fieldVal.Type()
- pkgFieldVal := pkgVal.FieldByName(outVal.Type().Field(i).Name)
- pkgFieldType := pkgFieldVal.Type()
-
- if strings.HasPrefix(pkgFieldType.String(), "db.JSON") {
- pkgFieldVal = pkgFieldVal.FieldByName("Val")
- pkgFieldType = pkgFieldVal.Type()
- }
-
- if pkgFieldType.AssignableTo(fieldType) {
- fieldVal.Set(pkgFieldVal)
- continue
- }
-
- if pkgFieldVal.Kind() == reflect.Map && pkgFieldType.Elem().AssignableTo(fieldType) {
- for _, override := range overrides {
- overrideVal := pkgFieldVal.MapIndex(reflect.ValueOf(override))
- if !overrideVal.IsValid() {
- continue
- }
-
- fieldVal.Set(overrideVal)
- break
- }
- }
- }
-
- return out
-}
-
func parseLangs(langs []string, tags []language.Tag) ([]string, error) {
out := make([]string, len(tags)+len(langs))
for i, tag := range tags {
diff --git a/internal/repos/find.go b/internal/repos/find.go
index b978cc6..957b3e3 100644
--- a/internal/repos/find.go
+++ b/internal/repos/find.go
@@ -22,11 +22,11 @@ package repos
import (
"context"
- "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
+ "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
)
-func (rs *Repos) FindPkgs(ctx context.Context, pkgs []string) (map[string][]db.Package, []string, error) {
- found := map[string][]db.Package{}
+func (rs *Repos) FindPkgs(ctx context.Context, pkgs []string) (map[string][]alrsh.Package, []string, error) {
+ found := map[string][]alrsh.Package{}
notFound := []string(nil)
for _, pkgName := range pkgs {
diff --git a/internal/repos/find_test.go b/internal/repos/find_test.go
index 384a31b..93fbfa9 100644
--- a/internal/repos/find_test.go
+++ b/internal/repos/find_test.go
@@ -24,8 +24,8 @@ import (
"strings"
"testing"
- "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/repos"
+ "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
)
@@ -89,31 +89,31 @@ func TestFindPkgsEmpty(t *testing.T) {
e.Db,
)
- err := e.Db.InsertPackage(e.Ctx, db.Package{
+ err := e.Db.InsertPackage(e.Ctx, alrsh.Package{
Name: "test1",
Repository: "default",
Version: "0.0.1",
Release: 1,
- Description: map[string]string{
+ Provides: []string{""},
+ Description: alrsh.OverridableFromMap(map[string]string{
"en": "Test package 1",
"ru": "Проверочный пакет 1",
- },
- Provides: []string{""},
+ }),
})
if err != nil {
t.Fatalf("Expected no error, got %s", err)
}
- err = e.Db.InsertPackage(e.Ctx, db.Package{
+ err = e.Db.InsertPackage(e.Ctx, alrsh.Package{
Name: "test2",
Repository: "default",
Version: "0.0.1",
Release: 1,
- Description: map[string]string{
+ Provides: []string{"test"},
+ Description: alrsh.OverridableFromMap(map[string]string{
"en": "Test package 2",
"ru": "Проверочный пакет 2",
- },
- Provides: []string{"test"},
+ }),
})
if err != nil {
t.Fatalf("Expected no error, got %s", err)
diff --git a/internal/repos/pull_internal_test.go b/internal/repos/pull_internal_test.go
index 8192cfe..6bd325b 100644
--- a/internal/repos/pull_internal_test.go
+++ b/internal/repos/pull_internal_test.go
@@ -27,6 +27,7 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
+ "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
)
@@ -84,10 +85,10 @@ build_deps=('golang')
result, err := database.GetPkgs(ctx, "1 = 1")
assert.NoError(t, err)
pkgCount := 0
- for _, dbPkg := range result {
- assert.Equal(t, "foo", dbPkg.Name)
- assert.Equal(t, map[string]string{"": "main desc"}, dbPkg.Description)
- assert.Equal(t, map[string][]string{"": {"sudo"}}, dbPkg.Depends)
+ for _, pkg := range result {
+ assert.Equal(t, "foo", pkg.Name)
+ assert.Equal(t, alrsh.OverridableFromMap(map[string]string{"": "main desc"}), pkg.Description)
+ assert.Equal(t, alrsh.OverridableFromMap(map[string][]string{"": {"sudo"}}), pkg.Depends)
pkgCount++
}
assert.Equal(t, 1, pkgCount)
@@ -119,18 +120,18 @@ meta_buz() {
assert.NoError(t, err)
pkgCount := 0
- for _, dbPkg := range result {
+ for _, pkg := range result {
if err != nil {
t.Errorf("Expected no error, got %s", err)
}
- if dbPkg.Name == "bar" {
- assert.Equal(t, map[string]string{"": "foo desc"}, dbPkg.Description)
- assert.Equal(t, map[string][]string{"": {"sudo"}}, dbPkg.Depends)
+ if pkg.Name == "bar" {
+ assert.Equal(t, alrsh.OverridableFromMap(map[string]string{"": "foo desc"}), pkg.Description)
+ assert.Equal(t, alrsh.OverridableFromMap(map[string][]string{"": {"sudo"}}), pkg.Depends)
}
- if dbPkg.Name == "buz" {
- assert.Equal(t, map[string]string{"": "main desc"}, dbPkg.Description)
- assert.Equal(t, map[string][]string{"": {"sudo", "doas"}}, dbPkg.Depends)
+ if pkg.Name == "buz" {
+ assert.Equal(t, alrsh.OverridableFromMap(map[string]string{"": "main desc"}), pkg.Description)
+ assert.Equal(t, alrsh.OverridableFromMap(map[string][]string{"": {"sudo", "doas"}}), pkg.Depends)
}
pkgCount++
}
diff --git a/internal/repos/utils.go b/internal/repos/utils.go
index 6bd93e0..5b6e1cd 100644
--- a/internal/repos/utils.go
+++ b/internal/repos/utils.go
@@ -18,12 +18,9 @@ package repos
import (
"context"
- "errors"
"fmt"
"io"
"path/filepath"
- "reflect"
- "strings"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
@@ -34,9 +31,7 @@ import (
"mvdan.cc/sh/v3/interp"
"mvdan.cc/sh/v3/syntax"
- "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
- "gitea.plemya-x.ru/Plemya-x/ALR/internal/parser"
- "gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/decoder"
+ "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
)
@@ -63,151 +58,21 @@ func parseScript(
syntaxParser *syntax.Parser,
runner *interp.Runner,
r io.ReadCloser,
-) ([]*db.Package, error) {
- fl, err := syntaxParser.Parse(r, "alr.sh")
+) ([]*alrsh.Package, error) {
+ f, err := alrsh.ReadFromIOReader(r, "/tmp")
if err != nil {
return nil, err
}
-
- runner.Reset()
- err = runner.Run(ctx, fl)
+ _, dbPkgs, err := f.ParseBuildVars(ctx, &distro.OSRelease{}, []string{})
if err != nil {
return nil, err
}
-
- d := decoder.New(&distro.OSRelease{}, runner)
- d.Overrides = false
- d.LikeDistros = false
-
- pkgNames, err := parser.ParseNames(d)
- if err != nil {
- return nil, fmt.Errorf("failed parsing package names: %w", err)
+ for _, pkg := range dbPkgs {
+ pkg.Repository = repo.Name
}
-
- if len(pkgNames.Names) == 0 {
- return nil, errors.New("package name is missing")
- }
-
- var dbPkgs []*db.Package
-
- if len(pkgNames.Names) > 1 {
- if pkgNames.BasePkgName == "" {
- pkgNames.BasePkgName = pkgNames.Names[0]
- }
- for _, pkgName := range pkgNames.Names {
- pkgInfo := PackageInfo{}
- funcName := fmt.Sprintf("meta_%s", pkgName)
- runner.Reset()
- err = runner.Run(ctx, fl)
- if err != nil {
- return nil, err
- }
- meta, ok := d.GetFuncWithSubshell(funcName)
- if !ok {
- return nil, fmt.Errorf("func %s is missing", funcName)
- }
- r, err := meta(ctx)
- if err != nil {
- return nil, err
- }
- d := decoder.New(&distro.OSRelease{}, r)
- d.Overrides = false
- d.LikeDistros = false
- err = d.DecodeVars(&pkgInfo)
- if err != nil {
- return nil, err
- }
- pkg := pkgInfo.ToPackage(repo.Name)
- resolveOverrides(r, pkg)
- pkg.Name = pkgName
- pkg.BasePkgName = pkgNames.BasePkgName
- dbPkgs = append(dbPkgs, pkg)
- }
-
- return dbPkgs, nil
- }
-
- pkg := EmptyPackage(repo.Name)
- err = d.DecodeVars(pkg)
- if err != nil {
- return nil, err
- }
- resolveOverrides(runner, pkg)
- dbPkgs = append(dbPkgs, pkg)
-
return dbPkgs, nil
}
-type PackageInfo struct {
- Version string `sh:"version,required"`
- Release int `sh:"release,required"`
- Epoch uint `sh:"epoch"`
- Architectures []string `sh:"architectures"`
- Licenses []string `sh:"license"`
- Provides []string `sh:"provides"`
- Conflicts []string `sh:"conflicts"`
- Replaces []string `sh:"replaces"`
-}
-
-func (inf *PackageInfo) ToPackage(repoName string) *db.Package {
- pkg := EmptyPackage(repoName)
- pkg.Version = inf.Version
- pkg.Release = inf.Release
- pkg.Epoch = inf.Epoch
- pkg.Architectures = inf.Architectures
- pkg.Licenses = inf.Licenses
- pkg.Provides = inf.Provides
- pkg.Conflicts = inf.Conflicts
- pkg.Replaces = inf.Replaces
- return pkg
-}
-
-func EmptyPackage(repoName string) *db.Package {
- return &db.Package{
- Group: map[string]string{},
- Summary: map[string]string{},
- Description: map[string]string{},
- Homepage: map[string]string{},
- Maintainer: map[string]string{},
- Depends: map[string][]string{},
- BuildDepends: map[string][]string{},
- Repository: repoName,
- }
-}
-
-var overridable = map[string]string{
- "deps": "Depends",
- "build_deps": "BuildDepends",
- "desc": "Description",
- "homepage": "Homepage",
- "maintainer": "Maintainer",
- "group": "Group",
- "summary": "Summary",
-}
-
-func resolveOverrides(runner *interp.Runner, pkg *db.Package) {
- pkgVal := reflect.ValueOf(pkg).Elem()
- for name, val := range runner.Vars {
- for prefix, field := range overridable {
- if strings.HasPrefix(name, prefix) {
- override := strings.TrimPrefix(name, prefix)
- override = strings.TrimPrefix(override, "_")
-
- varVal := pkgVal.FieldByName(field)
- varType := varVal.Type()
-
- switch varType.Elem().String() {
- case "[]string":
- varVal.SetMapIndex(reflect.ValueOf(override), reflect.ValueOf(val.List))
- case "string":
- varVal.SetMapIndex(reflect.ValueOf(override), reflect.ValueOf(val.Str))
- }
- break
- }
- }
- }
-}
-
func getHeadReference(r *git.Repository) (plumbing.ReferenceName, error) {
remote, err := r.Remote(git.DefaultRemoteName)
if err != nil {
diff --git a/internal/search/search.go b/internal/search/search.go
index 326906a..ca31bdc 100644
--- a/internal/search/search.go
+++ b/internal/search/search.go
@@ -22,12 +22,11 @@ package search
import (
"context"
- "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
- database "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
+ "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
)
type PackagesProvider interface {
- GetPkgs(ctx context.Context, where string, args ...any) ([]db.Package, error)
+ GetPkgs(ctx context.Context, where string, args ...any) ([]alrsh.Package, error)
}
type Searcher struct {
@@ -43,7 +42,7 @@ func New(pp PackagesProvider) *Searcher {
func (s *Searcher) Search(
ctx context.Context,
opts *SearchOptions,
-) ([]database.Package, error) {
+) ([]alrsh.Package, error) {
where, args := opts.WhereClause()
packages, err := s.pp.GetPkgs(ctx, where, args...)
return packages, err
diff --git a/internal/shutils/decoder/decoder.go b/internal/shutils/decoder/decoder.go
index ba31b12..0119664 100644
--- a/internal/shutils/decoder/decoder.go
+++ b/internal/shutils/decoder/decoder.go
@@ -22,6 +22,8 @@ package decoder
import (
"context"
"errors"
+ "fmt"
+ "log/slog"
"reflect"
"strings"
@@ -52,7 +54,7 @@ type InvalidTypeError struct {
}
func (ite InvalidTypeError) Error() string {
- return "variable '" + ite.name + "' is of type " + ite.vartype + ", but " + ite.exptype + " is expected"
+ return fmt.Sprintf("variable '%s' is of type %s, but %s is expected", ite.name, ite.vartype, ite.exptype)
}
// Decoder provides methods for decoding variable values
@@ -80,10 +82,58 @@ func (d *Decoder) DecodeVar(name string, val any) error {
dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
WeaklyTypedInput: true,
- Result: val,
- TagName: "sh",
+ DecodeHook: mapstructure.DecodeHookFuncValue(func(from, to reflect.Value) (interface{}, error) {
+ if strings.Contains(to.Type().String(), "alrsh.OverridableField") {
+ if to.Kind() != reflect.Ptr && to.CanAddr() {
+ to = to.Addr()
+ }
+
+ names, err := overrides.Resolve(d.info, overrides.DefaultOpts.WithName(name))
+ if err != nil {
+ return nil, err
+ }
+
+ isNotSet := true
+
+ setMethod := to.MethodByName("Set")
+ setResolvedMethod := to.MethodByName("SetResolved")
+
+ for _, varName := range names {
+ val := d.getVarNoOverrides(varName)
+ if val == nil {
+ continue
+ }
+
+ t := setMethod.Type().In(1)
+
+ newVal := from
+
+ if !newVal.Type().AssignableTo(t) {
+ newVal = reflect.New(t)
+ err = d.DecodeVar(name, newVal.Interface())
+ if err != nil {
+ return nil, err
+ }
+ newVal = newVal.Elem()
+ }
+
+ if isNotSet {
+ setResolvedMethod.Call([]reflect.Value{newVal})
+ }
+
+ override := strings.TrimPrefix(strings.TrimPrefix(varName, name), "_")
+ setMethod.Call([]reflect.Value{reflect.ValueOf(override), newVal})
+ }
+
+ return to, nil
+ }
+ return from.Interface(), nil
+ }),
+ Result: val,
+ TagName: "sh",
})
if err != nil {
+ slog.Warn("err", "err", err)
return err
}
@@ -243,23 +293,31 @@ func (d *Decoder) getVar(name string) *expand.Variable {
}
for _, varName := range names {
- val, ok := d.Runner.Vars[varName]
- if ok {
- // Resolve nameref variables
- _, resolved := val.Resolve(expand.FuncEnviron(func(s string) string {
- if val, ok := d.Runner.Vars[s]; ok {
- return val.String()
- }
- return ""
- }))
- val = resolved
-
- return &val
+ res := d.getVarNoOverrides(varName)
+ if res != nil {
+ return res
}
}
return nil
}
+func (d *Decoder) getVarNoOverrides(name string) *expand.Variable {
+ val, ok := d.Runner.Vars[name]
+ if ok {
+ // Resolve nameref variables
+ _, resolved := val.Resolve(expand.FuncEnviron(func(s string) string {
+ if val, ok := d.Runner.Vars[s]; ok {
+ return val.String()
+ }
+ return ""
+ }))
+ val = resolved
+
+ return &val
+ }
+ return nil
+}
+
func IsTruthy(value string) bool {
value = strings.ToLower(strings.TrimSpace(value))
return value == "true" || value == "yes" || value == "1"
diff --git a/internal/translations/default.pot b/internal/translations/default.pot
index 305ee50..ce8bc93 100644
--- a/internal/translations/default.pot
+++ b/internal/translations/default.pot
@@ -114,35 +114,35 @@ msgstr ""
msgid "Error parsing os-release file"
msgstr ""
-#: info.go:41
+#: info.go:42
msgid "Print information about a package"
msgstr ""
-#: info.go:46
+#: info.go:47
msgid "Show all information, not just for the current distro"
msgstr ""
-#: info.go:67
+#: info.go:68
msgid "Error getting packages"
msgstr ""
-#: info.go:82
+#: info.go:83
msgid "Command info expected at least 1 argument, got %d"
msgstr ""
-#: info.go:102
+#: info.go:104
msgid "Error finding packages"
msgstr ""
-#: info.go:116
+#: info.go:118
msgid "Can't detect system language"
msgstr ""
-#: info.go:133
+#: info.go:135
msgid "Error resolving overrides"
msgstr ""
-#: info.go:141 info.go:146
+#: info.go:144 info.go:149
msgid "Error encoding script variables"
msgstr ""
@@ -174,19 +174,19 @@ msgstr ""
msgid "Error removing packages"
msgstr ""
-#: internal/build/build.go:375
+#: internal/build/build.go:376
msgid "Building package"
msgstr ""
-#: internal/build/build.go:404
+#: internal/build/build.go:405
msgid "The checksums array must be the same length as sources"
msgstr ""
-#: internal/build/build.go:446
+#: internal/build/build.go:447
msgid "Downloading sources"
msgstr ""
-#: internal/build/build.go:538
+#: internal/build/build.go:539
msgid "Installing dependencies"
msgstr ""
@@ -224,15 +224,15 @@ msgstr ""
msgid "Building package metadata"
msgstr ""
-#: internal/build/script_executor.go:275
+#: internal/build/script_executor.go:276
msgid "Executing prepare()"
msgstr ""
-#: internal/build/script_executor.go:284
+#: internal/build/script_executor.go:285
msgid "Executing build()"
msgstr ""
-#: internal/build/script_executor.go:313 internal/build/script_executor.go:333
+#: internal/build/script_executor.go:314 internal/build/script_executor.go:334
msgid "Executing %s()"
msgstr ""
@@ -244,15 +244,15 @@ msgstr ""
msgid "Error initialization database"
msgstr ""
-#: internal/cliutils/app_builder/builder.go:135
+#: internal/cliutils/app_builder/builder.go:142
msgid "Error pulling repositories"
msgstr ""
-#: internal/cliutils/app_builder/builder.go:152
+#: internal/cliutils/app_builder/builder.go:159
msgid "Error parsing os release"
msgstr ""
-#: internal/cliutils/app_builder/builder.go:165
+#: internal/cliutils/app_builder/builder.go:172
msgid "Unable to detect a supported package manager on the system"
msgstr ""
@@ -336,17 +336,17 @@ msgstr ""
msgid "OPTIONS"
msgstr ""
-#: internal/cliutils/utils.go:69
+#: internal/cliutils/utils.go:72
msgid ""
"This command is deprecated and would be removed in the future, use \"%s\" "
"instead!"
msgstr ""
-#: internal/db/db.go:95
+#: internal/db/db.go:76
msgid "Database version mismatch; resetting"
msgstr ""
-#: internal/db/db.go:101
+#: internal/db/db.go:82
msgid ""
"Database version does not exist. Run alr fix if something isn't working."
msgstr ""
@@ -541,14 +541,14 @@ msgstr ""
msgid "Error while executing search"
msgstr ""
-#: upgrade.go:47
+#: upgrade.go:48
msgid "Upgrade all installed packages"
msgstr ""
-#: upgrade.go:105 upgrade.go:122
+#: upgrade.go:106 upgrade.go:123
msgid "Error checking for updates"
msgstr ""
-#: upgrade.go:125
+#: upgrade.go:126
msgid "There is nothing to do."
msgstr ""
diff --git a/internal/translations/po/ru/default.po b/internal/translations/po/ru/default.po
index 7df88f9..dd7d42c 100644
--- a/internal/translations/po/ru/default.po
+++ b/internal/translations/po/ru/default.po
@@ -121,35 +121,35 @@ msgstr "Такой вспомогательной команды нет"
msgid "Error parsing os-release file"
msgstr "Ошибка при разборе файла выпуска операционной системы"
-#: info.go:41
+#: info.go:42
msgid "Print information about a package"
msgstr "Отобразить информацию о пакете"
-#: info.go:46
+#: info.go:47
msgid "Show all information, not just for the current distro"
msgstr "Показывать всю информацию, не только для текущего дистрибутива"
-#: info.go:67
+#: info.go:68
msgid "Error getting packages"
msgstr "Ошибка при получении пакетов"
-#: info.go:82
+#: info.go:83
msgid "Command info expected at least 1 argument, got %d"
msgstr "Для команды info ожидался хотя бы 1 аргумент, получено %d"
-#: info.go:102
+#: info.go:104
msgid "Error finding packages"
msgstr "Ошибка при поиске пакетов"
-#: info.go:116
+#: info.go:118
msgid "Can't detect system language"
msgstr "Ошибка при определении языка системы"
-#: info.go:133
+#: info.go:135
msgid "Error resolving overrides"
msgstr "Ошибка устранения переорпеделений"
-#: info.go:141 info.go:146
+#: info.go:144 info.go:149
msgid "Error encoding script variables"
msgstr "Ошибка кодирования переменных скрита"
@@ -181,19 +181,19 @@ msgstr "Для команды remove ожидался хотя бы 1 аргум
msgid "Error removing packages"
msgstr "Ошибка при удалении пакетов"
-#: internal/build/build.go:375
+#: internal/build/build.go:376
msgid "Building package"
msgstr "Сборка пакета"
-#: internal/build/build.go:404
+#: internal/build/build.go:405
msgid "The checksums array must be the same length as sources"
msgstr "Массив контрольных сумм должен быть той же длины, что и источники"
-#: internal/build/build.go:446
+#: internal/build/build.go:447
msgid "Downloading sources"
msgstr "Скачивание источников"
-#: internal/build/build.go:538
+#: internal/build/build.go:539
msgid "Installing dependencies"
msgstr "Установка зависимостей"
@@ -235,15 +235,15 @@ msgstr ""
msgid "Building package metadata"
msgstr "Сборка метаданных пакета"
-#: internal/build/script_executor.go:275
+#: internal/build/script_executor.go:276
msgid "Executing prepare()"
msgstr "Выполнение prepare()"
-#: internal/build/script_executor.go:284
+#: internal/build/script_executor.go:285
msgid "Executing build()"
msgstr "Выполнение build()"
-#: internal/build/script_executor.go:313 internal/build/script_executor.go:333
+#: internal/build/script_executor.go:314 internal/build/script_executor.go:334
msgid "Executing %s()"
msgstr "Выполнение %s()"
@@ -255,15 +255,15 @@ msgstr "Ошибка при загрузке"
msgid "Error initialization database"
msgstr "Ошибка инициализации базы данных"
-#: internal/cliutils/app_builder/builder.go:135
+#: internal/cliutils/app_builder/builder.go:142
msgid "Error pulling repositories"
msgstr "Ошибка при извлечении репозиториев"
-#: internal/cliutils/app_builder/builder.go:152
+#: internal/cliutils/app_builder/builder.go:159
msgid "Error parsing os release"
msgstr "Ошибка при разборе файла выпуска операционной системы"
-#: internal/cliutils/app_builder/builder.go:165
+#: internal/cliutils/app_builder/builder.go:172
msgid "Unable to detect a supported package manager on the system"
msgstr "Не удалось обнаружить поддерживаемый менеджер пакетов в системе"
@@ -347,7 +347,7 @@ msgstr "КАТЕГОРИЯ"
msgid "OPTIONS"
msgstr "ПАРАМЕТРЫ"
-#: internal/cliutils/utils.go:69
+#: internal/cliutils/utils.go:72
msgid ""
"This command is deprecated and would be removed in the future, use \"%s\" "
"instead!"
@@ -355,11 +355,11 @@ msgstr ""
"Эта команда устарела и будет удалена в будущем, используйте вместо нее \"%s"
"\"!"
-#: internal/db/db.go:95
+#: internal/db/db.go:76
msgid "Database version mismatch; resetting"
msgstr "Несоответствие версий базы данных; сброс настроек"
-#: internal/db/db.go:101
+#: internal/db/db.go:82
msgid ""
"Database version does not exist. Run alr fix if something isn't working."
msgstr ""
@@ -557,15 +557,15 @@ msgstr "Иcкать по provides"
msgid "Error while executing search"
msgstr "Ошибка при выполнении поиска"
-#: upgrade.go:47
+#: upgrade.go:48
msgid "Upgrade all installed packages"
msgstr "Обновить все установленные пакеты"
-#: upgrade.go:105 upgrade.go:122
+#: upgrade.go:106 upgrade.go:123
msgid "Error checking for updates"
msgstr "Ошибка при проверке обновлений"
-#: upgrade.go:125
+#: upgrade.go:126
msgid "There is nothing to do."
msgstr "Здесь нечего делать."
diff --git a/list.go b/list.go
index 4fbcd14..8d1ba69 100644
--- a/list.go
+++ b/list.go
@@ -32,9 +32,9 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/build"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
appbuilder "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils/app_builder"
- database "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/manager"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/utils"
+ "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
)
func ListCmd() *cli.Command {
@@ -69,9 +69,9 @@ func ListCmd() *cli.Command {
WithConfig().
WithDB().
WithManager().
+ WithDistroInfo().
// autoPull only
WithRepos().
- WithDistroInfo().
Build()
if err != nil {
return err
@@ -159,7 +159,7 @@ func ListCmd() *cli.Command {
}
type packageInfo struct {
- Package *database.Package
+ Package *alrsh.Package
Version string
}
diff --git a/pkg/alrsh/alrsh.go b/pkg/alrsh/alrsh.go
index 37a723e..f2237b9 100644
--- a/pkg/alrsh/alrsh.go
+++ b/pkg/alrsh/alrsh.go
@@ -38,7 +38,7 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
)
-type ALRSh struct {
+type ScriptFile struct {
file *syntax.File
path string
}
@@ -72,97 +72,134 @@ func createBuildEnvVars(info *distro.OSRelease, dirs types.Directories) []string
return env
}
-func (s *ALRSh) ParseBuildVars(ctx context.Context, info *distro.OSRelease, packages []string) (string, []*types.BuildVars, error) {
- varsOfPackages := []*types.BuildVars{}
-
- scriptDir := filepath.Dir(s.path)
- env := createBuildEnvVars(info, types.Directories{ScriptDir: scriptDir})
-
- runner, err := interp.New(
- interp.Env(expand.ListEnviron(env...)), // Устанавливаем окружение
- interp.StdIO(os.Stdin, os.Stderr, os.Stderr), // Устанавливаем стандартный ввод-вывод
- interp.ExecHandler(helpers.Restricted.ExecHandler(handlers.NopExec)), // Ограничиваем выполнение
- interp.ReadDirHandler2(handlers.RestrictedReadDir(scriptDir)), // Ограничиваем чтение директорий
- interp.StatHandler(handlers.RestrictedStat(scriptDir)), // Ограничиваем доступ к статистике файлов
- interp.OpenHandler(handlers.RestrictedOpen(scriptDir)), // Ограничиваем открытие файлов
- interp.Dir(scriptDir),
- )
+func (s *ScriptFile) ParseBuildVars(ctx context.Context, info *distro.OSRelease, packages []string) (string, []*Package, error) {
+ runner, err := s.createRunner(info)
if err != nil {
return "", nil, err
}
- err = runner.Run(ctx, s.file) // Запускаем скрипт
+ if err := runScript(ctx, runner, s.file); err != nil {
+ return "", nil, err
+ }
+
+ dec := newDecoder(info, runner)
+
+ pkgNames, err := ParseNames(dec)
if err != nil {
return "", nil, err
}
- dec := decoder.New(info, runner) // Создаём новый декодер
-
- type Packages struct {
- BasePkgName string `sh:"basepkg_name"`
- Names []string `sh:"name"`
- }
-
- var pkgs Packages
- err = dec.DecodeVars(&pkgs)
- if err != nil {
- return "", nil, err
- }
-
- if len(pkgs.Names) == 0 {
+ if len(pkgNames.Names) == 0 {
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
- }
- varsOfPackages = append(varsOfPackages, &vars)
-
- return vars.Name, varsOfPackages, nil
+ targetPackages := packages
+ if len(targetPackages) == 0 {
+ targetPackages = pkgNames.Names
}
- var pkgNames []string
-
- if len(packages) != 0 {
- pkgNames = packages
- } else {
- pkgNames = pkgs.Names
+ varsOfPackages, err := s.createPackagesForBuildVars(ctx, dec, pkgNames, targetPackages)
+ if err != nil {
+ return "", nil, err
}
- for _, pkgName := range pkgNames {
- var preVars types.BuildVarsPre
- funcName := fmt.Sprintf("meta_%s", pkgName)
- meta, ok := dec.GetFuncWithSubshell(funcName)
- if !ok {
- return "", nil, fmt.Errorf("func %s is missing", funcName)
- }
- r, err := meta(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
- vars.Base = pkgs.BasePkgName
-
- varsOfPackages = append(varsOfPackages, &vars)
+ baseName := pkgNames.BasePkgName
+ if len(pkgNames.Names) == 1 {
+ baseName = pkgNames.Names[0]
}
- return pkgs.BasePkgName, varsOfPackages, nil
+ return baseName, varsOfPackages, nil
}
-func (a *ALRSh) Path() string {
+func (s *ScriptFile) createRunner(info *distro.OSRelease) (*interp.Runner, error) {
+ scriptDir := filepath.Dir(s.path)
+ env := createBuildEnvVars(info, types.Directories{ScriptDir: scriptDir})
+
+ return interp.New(
+ interp.Env(expand.ListEnviron(env...)),
+ interp.StdIO(os.Stdin, os.Stderr, os.Stderr),
+ interp.ExecHandler(helpers.Restricted.ExecHandler(handlers.NopExec)),
+ interp.ReadDirHandler2(handlers.RestrictedReadDir(scriptDir)),
+ interp.StatHandler(handlers.RestrictedStat(scriptDir)),
+ interp.OpenHandler(handlers.RestrictedOpen(scriptDir)),
+ interp.Dir(scriptDir),
+ )
+}
+
+func (s *ScriptFile) createPackagesForBuildVars(
+ ctx context.Context,
+ dec *decoder.Decoder,
+ pkgNames *PackageNames,
+ targetPackages []string,
+) ([]*Package, error) {
+ var varsOfPackages []*Package
+
+ if len(pkgNames.Names) == 1 {
+ var pkg Package
+ pkg.Name = pkgNames.Names[0]
+ if err := dec.DecodeVars(&pkg); err != nil {
+ return nil, err
+ }
+ varsOfPackages = append(varsOfPackages, &pkg)
+ return varsOfPackages, nil
+ }
+
+ for _, pkgName := range targetPackages {
+ pkg, err := s.createPackageFromMeta(ctx, dec, pkgName, pkgNames.BasePkgName)
+ if err != nil {
+ return nil, err
+ }
+ varsOfPackages = append(varsOfPackages, pkg)
+ }
+
+ return varsOfPackages, nil
+}
+
+func (s *ScriptFile) createPackageFromMeta(
+ ctx context.Context,
+ dec *decoder.Decoder,
+ pkgName, basePkgName string,
+) (*Package, error) {
+ funcName := fmt.Sprintf("meta_%s", pkgName)
+ meta, ok := dec.GetFuncWithSubshell(funcName)
+ if !ok {
+ return nil, fmt.Errorf("func %s is missing", funcName)
+ }
+
+ metaRunner, err := meta(ctx)
+ if err != nil {
+ return nil, err
+ }
+
+ metaDecoder := decoder.New(&distro.OSRelease{}, metaRunner)
+
+ var vars Package
+ if err := metaDecoder.DecodeVars(&vars); err != nil {
+ return nil, err
+ }
+
+ vars.Name = pkgName
+ vars.BasePkgName = basePkgName
+
+ return &vars, nil
+}
+
+func runScript(ctx context.Context, runner *interp.Runner, fl *syntax.File) error {
+ runner.Reset()
+ return runner.Run(ctx, fl)
+}
+
+func newDecoder(info *distro.OSRelease, runner *interp.Runner) *decoder.Decoder {
+ d := decoder.New(info, runner)
+ // d.Overrides = false
+ // d.LikeDistros = false
+ return d
+}
+
+func (a *ScriptFile) Path() string {
return a.path
}
-func (a *ALRSh) File() *syntax.File {
+func (a *ScriptFile) File() *syntax.File {
return a.file
}
diff --git a/pkg/alrsh/gob.go b/pkg/alrsh/gob.go
index e1ad501..bb81815 100644
--- a/pkg/alrsh/gob.go
+++ b/pkg/alrsh/gob.go
@@ -24,7 +24,7 @@ import (
"mvdan.cc/sh/v3/syntax/typedjson"
)
-func (s *ALRSh) GobEncode() ([]byte, error) {
+func (s *ScriptFile) GobEncode() ([]byte, error) {
var buf bytes.Buffer
enc := gob.NewEncoder(&buf)
if err := enc.Encode(s.path); err != nil {
@@ -41,7 +41,7 @@ func (s *ALRSh) GobEncode() ([]byte, error) {
return buf.Bytes(), nil
}
-func (s *ALRSh) GobDecode(data []byte) error {
+func (s *ScriptFile) GobDecode(data []byte) error {
buf := bytes.NewBuffer(data)
dec := gob.NewDecoder(buf)
if err := dec.Decode(&s.path); err != nil {
diff --git a/pkg/alrsh/overridable.go b/pkg/alrsh/overridable.go
new file mode 100644
index 0000000..f0ab785
--- /dev/null
+++ b/pkg/alrsh/overridable.go
@@ -0,0 +1,146 @@
+// ALR - Any Linux Repository
+// Copyright (C) 2025 The ALR Authors
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+package alrsh
+
+import (
+ "bytes"
+ "encoding/gob"
+ "encoding/json"
+)
+
+type OverridableField[T any] struct {
+ data map[string]T
+ // It can't be a pointer
+ //
+ // See https://gitea.com/xorm/xorm/issues/2431
+ resolved T
+}
+
+func (f *OverridableField[T]) Set(key string, value T) {
+ if f.data == nil {
+ f.data = make(map[string]T)
+ }
+ f.data[key] = value
+}
+
+func (f *OverridableField[T]) Get(key string) T {
+ if f.data == nil {
+ f.data = make(map[string]T)
+ }
+ return f.data[key]
+}
+
+func (f *OverridableField[T]) Has(key string) (T, bool) {
+ if f.data == nil {
+ f.data = make(map[string]T)
+ }
+ val, ok := f.data[key]
+ return val, ok
+}
+
+func (f *OverridableField[T]) SetResolved(value T) {
+ f.resolved = value
+}
+
+func (f *OverridableField[T]) Resolved() T {
+ return f.resolved
+}
+
+func (f *OverridableField[T]) All() map[string]T {
+ return f.data
+}
+
+func (o *OverridableField[T]) Resolve(overrides []string) {
+ for _, override := range overrides {
+ if v, ok := o.Has(override); ok {
+ o.SetResolved(v)
+ }
+ }
+}
+
+func (f *OverridableField[T]) ToDB() ([]byte, error) {
+ var data map[string]T
+
+ if f.data == nil {
+ data = make(map[string]T)
+ } else {
+ data = f.data
+ }
+
+ return json.Marshal(data)
+}
+
+func (f *OverridableField[T]) FromDB(data []byte) error {
+ if len(data) == 0 {
+ *f = OverridableField[T]{data: make(map[string]T)}
+ return nil
+ }
+
+ var temp map[string]T
+ if err := json.Unmarshal(data, &temp); err != nil {
+ return err
+ }
+
+ if temp == nil {
+ temp = make(map[string]T)
+ }
+
+ *f = OverridableField[T]{data: temp}
+ return nil
+}
+
+type overridableFieldGobPayload[T any] struct {
+ Data map[string]T
+ Resolved T
+}
+
+func (f *OverridableField[T]) GobEncode() ([]byte, error) {
+ var buf bytes.Buffer
+ enc := gob.NewEncoder(&buf)
+
+ payload := overridableFieldGobPayload[T]{
+ Data: f.data,
+ Resolved: f.resolved,
+ }
+
+ if err := enc.Encode(payload); err != nil {
+ return nil, err
+ }
+ return buf.Bytes(), nil
+}
+
+func (f *OverridableField[T]) GobDecode(data []byte) error {
+ dec := gob.NewDecoder(bytes.NewBuffer(data))
+
+ var payload overridableFieldGobPayload[T]
+ if err := dec.Decode(&payload); err != nil {
+ return err
+ }
+
+ f.data = payload.Data
+ f.resolved = payload.Resolved
+ return nil
+}
+
+func OverridableFromMap[T any](data map[string]T) OverridableField[T] {
+ if data == nil {
+ data = make(map[string]T)
+ }
+ return OverridableField[T]{
+ data: data,
+ }
+}
diff --git a/pkg/alrsh/package.go b/pkg/alrsh/package.go
new file mode 100644
index 0000000..c24d0b2
--- /dev/null
+++ b/pkg/alrsh/package.go
@@ -0,0 +1,105 @@
+// ALR - Any Linux Repository
+// Copyright (C) 2025 The ALR Authors
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+package alrsh
+
+import (
+ "fmt"
+ "reflect"
+ "strings"
+
+ "gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/decoder"
+)
+
+type PackageNames struct {
+ BasePkgName string `sh:"basepkg_name"`
+ Names []string `sh:"name"`
+}
+
+func ParseNames(dec *decoder.Decoder) (*PackageNames, error) {
+ var pkgs PackageNames
+ err := dec.DecodeVars(&pkgs)
+ if err != nil {
+ return nil, fmt.Errorf("fail parse names: %w", err)
+ }
+ return &pkgs, nil
+}
+
+type Package struct {
+ Repository string `xorm:"pk 'repository'"`
+ Name string `xorm:"pk 'name'"`
+ BasePkgName string `xorm:"notnull 'basepkg_name'"`
+
+ Version string `sh:"version" xorm:"notnull 'version'"`
+ Release int `sh:"release" xorm:"notnull 'release'"`
+ Epoch uint `sh:"epoch" xorm:"'epoch'"`
+ Architectures []string `sh:"architectures" xorm:"json 'architectures'"`
+ Licenses []string `sh:"license" xorm:"json 'licenses'"`
+ Provides []string `sh:"provides" xorm:"json 'provides'"`
+ Conflicts []string `sh:"conflicts" xorm:"json 'conflicts'"`
+ Replaces []string `sh:"replaces" xorm:"json 'replaces'"`
+
+ Summary OverridableField[string] `sh:"summary" xorm:"'summary'"`
+ Description OverridableField[string] `sh:"desc" xorm:"'description'"`
+ Group OverridableField[string] `sh:"group" xorm:"'group_name'"`
+ Homepage OverridableField[string] `sh:"homepage" xorm:"'homepage'"`
+ Maintainer OverridableField[string] `sh:"maintainer" xorm:"'maintainer'"`
+ Depends OverridableField[[]string] `sh:"deps" xorm:"'depends'"`
+ BuildDepends OverridableField[[]string] `sh:"build_deps" xorm:"'builddepends'"`
+ OptDepends OverridableField[[]string] `sh:"opt_deps" xorm:"'optdepends'"`
+ Sources OverridableField[[]string] `sh:"sources" xorm:"-"`
+ Checksums OverridableField[[]string] `sh:"checksums" xorm:"-"`
+ Backup OverridableField[[]string] `sh:"backup" xorm:"-"`
+ Scripts OverridableField[Scripts] `sh:"scripts" xorm:"-"`
+ AutoReq OverridableField[[]string] `sh:"auto_req" xorm:"-"`
+ AutoProv OverridableField[[]string] `sh:"auto_prov" xorm:"-"`
+ AutoReqSkipList OverridableField[[]string] `sh:"auto_req_skiplist" xorm:"-"`
+ AutoProvSkipList OverridableField[[]string] `sh:"auto_prov_skiplist" xorm:"-"`
+}
+
+type Scripts struct {
+ PreInstall string `sh:"preinstall"`
+ PostInstall string `sh:"postinstall"`
+ PreRemove string `sh:"preremove"`
+ PostRemove string `sh:"postremove"`
+ PreUpgrade string `sh:"preupgrade"`
+ PostUpgrade string `sh:"postupgrade"`
+ PreTrans string `sh:"pretrans"`
+ PostTrans string `sh:"posttrans"`
+}
+
+func ResolvePackage(p *Package, overrides []string) {
+ val := reflect.ValueOf(p).Elem()
+ typ := val.Type()
+
+ for i := range val.NumField() {
+ field := val.Field(i)
+ fieldType := typ.Field(i)
+
+ if !field.CanInterface() {
+ continue
+ }
+
+ if field.Kind() == reflect.Struct && strings.HasPrefix(fieldType.Type.String(), "alrsh.OverridableField") {
+ of := field.Addr().Interface()
+ if res, ok := of.(interface {
+ Resolve([]string)
+ }); ok {
+ res.Resolve(overrides)
+ }
+ }
+ }
+}
diff --git a/pkg/alrsh/read.go b/pkg/alrsh/read.go
index 360e44d..d5d7d74 100644
--- a/pkg/alrsh/read.go
+++ b/pkg/alrsh/read.go
@@ -18,6 +18,7 @@ package alrsh
import (
"fmt"
+ "io"
"io/fs"
"os"
@@ -30,23 +31,27 @@ func (fs *localFs) Open(name string) (fs.File, error) {
return os.Open(name)
}
-func ReadFromFS(fsys fs.FS, script string) (*ALRSh, error) {
+func ReadFromIOReader(r io.Reader, script string) (*ScriptFile, error) {
+ file, err := syntax.NewParser().Parse(r, "alr.sh")
+ if err != nil {
+ return nil, err
+ }
+ return &ScriptFile{
+ file: file,
+ path: script,
+ }, nil
+}
+
+func ReadFromFS(fsys fs.FS, script string) (*ScriptFile, error) {
fl, err := fsys.Open(script)
if err != nil {
return nil, fmt.Errorf("failed to open alr.sh: %w", err)
}
defer fl.Close()
- file, err := syntax.NewParser().Parse(fl, "alr.sh")
- if err != nil {
- return nil, err
- }
- return &ALRSh{
- file: file,
- path: script,
- }, nil
+ return ReadFromIOReader(fl, script)
}
-func ReadFromLocal(script string) (*ALRSh, error) {
+func ReadFromLocal(script string) (*ScriptFile, error) {
return ReadFromFS(&localFs{}, script)
}
diff --git a/pkg/types/build.go b/pkg/types/build.go
index 350a1f0..7e253b0 100644
--- a/pkg/types/build.go
+++ b/pkg/types/build.go
@@ -24,49 +24,6 @@ type BuildOpts struct {
Interactive bool
}
-type BuildVarsPre struct {
- Version string `sh:"version,required"`
- Release int `sh:"release,required"`
- Epoch uint `sh:"epoch"`
- Summary string `sh:"summary"`
- Description string `sh:"desc"`
- Group string `sh:"group"`
- Homepage string `sh:"homepage"`
- Maintainer string `sh:"maintainer"`
- Architectures []string `sh:"architectures"`
- Licenses []string `sh:"license"`
- Provides []string `sh:"provides"`
- Conflicts []string `sh:"conflicts"`
- Depends []string `sh:"deps"`
- BuildDepends []string `sh:"build_deps"`
- OptDepends []string `sh:"opt_deps"`
- Replaces []string `sh:"replaces"`
- Sources []string `sh:"sources"`
- Checksums []string `sh:"checksums"`
- Backup []string `sh:"backup"`
- Scripts Scripts `sh:"scripts"`
- AutoReq []string `sh:"auto_req"`
- AutoProv []string `sh:"auto_prov"`
- AutoReqSkipList []string `sh:"auto_req_skiplist"`
- AutoProvSkipList []string `sh:"auto_prov_skiplist"`
-}
-
-func (bv *BuildVarsPre) ToBuildVars() BuildVars {
- return BuildVars{
- Name: "",
- Base: "",
- BuildVarsPre: *bv,
- }
-}
-
-// BuildVars represents the script variables required
-// to build a package
-type BuildVars struct {
- Name string `sh:"name,required"`
- Base string
- BuildVarsPre
-}
-
type Scripts struct {
PreInstall string `sh:"preinstall"`
PostInstall string `sh:"postinstall"`
diff --git a/search.go b/search.go
index 5b32685..02c88ae 100644
--- a/search.go
+++ b/search.go
@@ -27,10 +27,10 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
appbuilder "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils/app_builder"
- "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/search"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/utils"
+ "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
)
@@ -139,27 +139,16 @@ func SearchCmd() *cli.Command {
}
}
- for _, dbPkg := range packages {
- var pkg any
- if !all {
- pkg = overrides.ResolvePackage(&dbPkg, names)
- } else {
- pkg = &dbPkg
- }
-
+ for _, pkg := range packages {
+ alrsh.ResolvePackage(&pkg, names)
if tmpl != nil {
- err = tmpl.Execute(os.Stdout, pkg)
+ err = tmpl.Execute(os.Stdout, &pkg)
if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error executing template"), err)
}
fmt.Println()
} else {
- switch v := pkg.(type) {
- case *overrides.ResolvedPackage:
- fmt.Println(v.Name)
- case *db.Package:
- fmt.Println(v.Name)
- }
+ fmt.Println(pkg.Name)
}
}
diff --git a/upgrade.go b/upgrade.go
index 2183e84..254edaa 100644
--- a/upgrade.go
+++ b/upgrade.go
@@ -37,6 +37,7 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/overrides"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/search"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/utils"
+ "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
)
@@ -130,8 +131,8 @@ func UpgradeCmd() *cli.Command {
}
}
-func mapUptatesInfoToPackages(updates []UpdateInfo) []database.Package {
- var pkgs []database.Package
+func mapUptatesInfoToPackages(updates []UpdateInfo) []alrsh.Package {
+ var pkgs []alrsh.Package
for _, info := range updates {
pkgs = append(pkgs, *info.Package)
}
@@ -139,7 +140,7 @@ func mapUptatesInfoToPackages(updates []UpdateInfo) []database.Package {
}
type UpdateInfo struct {
- Package *database.Package
+ Package *alrsh.Package
FromVersion string
ToVersion string