forked from Plemya-x/ALR
refactor: keep only one struct for package
This commit is contained in:
@ -11,7 +11,7 @@
|
|||||||
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
|
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
|
||||||
<text x="33.5" y="15" fill="#010101" fill-opacity=".3">coverage</text>
|
<text x="33.5" y="15" fill="#010101" fill-opacity=".3">coverage</text>
|
||||||
<text x="33.5" y="14">coverage</text>
|
<text x="33.5" y="14">coverage</text>
|
||||||
<text x="86" y="15" fill="#010101" fill-opacity=".3">16.5%</text>
|
<text x="86" y="15" fill="#010101" fill-opacity=".3">17.6%</text>
|
||||||
<text x="86" y="14">16.5%</text>
|
<text x="86" y="14">17.6%</text>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 926 B After Width: | Height: | Size: 926 B |
@ -31,8 +31,8 @@ func TestE2EGroupAndSummaryField(t *testing.T) {
|
|||||||
RPM_SYSTEMS,
|
RPM_SYSTEMS,
|
||||||
func(t *testing.T, r e2e.Runnable) {
|
func(t *testing.T, r e2e.Runnable) {
|
||||||
defaultPrepare(t, r)
|
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 \"{{.Group.Resolved}}\" | 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 \"{{.Summary.Resolved}}\" | grep \"^Custom summary$\"")
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
5
info.go
5
info.go
@ -32,6 +32,7 @@ import (
|
|||||||
appbuilder "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils/app_builder"
|
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/overrides"
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/utils"
|
"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/distro"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -88,6 +89,7 @@ func InfoCmd() *cli.Command {
|
|||||||
New(ctx).
|
New(ctx).
|
||||||
WithConfig().
|
WithConfig().
|
||||||
WithDB().
|
WithDB().
|
||||||
|
WithDistroInfo().
|
||||||
WithRepos().
|
WithRepos().
|
||||||
Build()
|
Build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -136,7 +138,8 @@ func InfoCmd() *cli.Command {
|
|||||||
|
|
||||||
for _, pkg := range pkgs {
|
for _, pkg := range pkgs {
|
||||||
if !all {
|
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 {
|
if err != nil {
|
||||||
return cliutils.FormatCliExit(gotext.Get("Error encoding script variables"), err)
|
return cliutils.FormatCliExit(gotext.Get("Error encoding script variables"), err)
|
||||||
}
|
}
|
||||||
|
@ -24,13 +24,13 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
|
||||||
"github.com/leonelquinteros/gotext"
|
"github.com/leonelquinteros/gotext"
|
||||||
|
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
|
"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/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/internal/manager"
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
|
"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/distro"
|
||||||
@ -158,7 +158,7 @@ func GetBuiltName(deps []*BuiltDep) []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PackageFinder interface {
|
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 {
|
type Config interface {
|
||||||
@ -173,12 +173,12 @@ type FunctionsOutput struct {
|
|||||||
// EXECUTORS
|
// EXECUTORS
|
||||||
|
|
||||||
type ScriptResolverExecutor interface {
|
type ScriptResolverExecutor interface {
|
||||||
ResolveScript(ctx context.Context, pkg *db.Package) *ScriptInfo
|
ResolveScript(ctx context.Context, pkg *alrsh.Package) *ScriptInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
type ScriptExecutor interface {
|
type ScriptExecutor interface {
|
||||||
ReadScript(ctx context.Context, scriptPath string) (*alrsh.ALRSh, error)
|
ReadScript(ctx context.Context, scriptPath string) (*alrsh.ScriptFile, error)
|
||||||
ExecuteFirstPass(ctx context.Context, input *BuildInput, sf *alrsh.ALRSh) (string, []*types.BuildVars, error)
|
ExecuteFirstPass(ctx context.Context, input *BuildInput, sf *alrsh.ScriptFile) (string, []*alrsh.Package, error)
|
||||||
PrepareDirs(
|
PrepareDirs(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
input *BuildInput,
|
input *BuildInput,
|
||||||
@ -187,8 +187,8 @@ type ScriptExecutor interface {
|
|||||||
ExecuteSecondPass(
|
ExecuteSecondPass(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
input *BuildInput,
|
input *BuildInput,
|
||||||
sf *alrsh.ALRSh,
|
sf *alrsh.ScriptFile,
|
||||||
varsOfPackages []*types.BuildVars,
|
varsOfPackages []*alrsh.Package,
|
||||||
repoDeps []string,
|
repoDeps []string,
|
||||||
builtDeps []*BuiltDep,
|
builtDeps []*BuiltDep,
|
||||||
basePkg string,
|
basePkg string,
|
||||||
@ -196,18 +196,18 @@ type ScriptExecutor interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type CacheExecutor 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 {
|
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 {
|
type CheckerExecutor interface {
|
||||||
PerformChecks(
|
PerformChecks(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
input *BuildInput,
|
input *BuildInput,
|
||||||
vars *types.BuildVars,
|
vars *alrsh.Package,
|
||||||
) (bool, error)
|
) (bool, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,7 +285,7 @@ func (b *BuildArgs) PkgFormat() string {
|
|||||||
|
|
||||||
type BuildPackageFromDbArgs struct {
|
type BuildPackageFromDbArgs struct {
|
||||||
BuildArgs
|
BuildArgs
|
||||||
Package *db.Package
|
Package *alrsh.Package
|
||||||
Packages []string
|
Packages []string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,19 +334,19 @@ func (b *Builder) BuildPackage(
|
|||||||
slog.Debug("ReadScript")
|
slog.Debug("ReadScript")
|
||||||
sf, err := b.scriptExecutor.ReadScript(ctx, scriptPath)
|
sf, err := b.scriptExecutor.ReadScript(ctx, scriptPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("failed reading script: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
slog.Debug("ExecuteFirstPass")
|
slog.Debug("ExecuteFirstPass")
|
||||||
basePkg, varsOfPackages, err := b.scriptExecutor.ExecuteFirstPass(ctx, input, sf)
|
basePkg, varsOfPackages, err := b.scriptExecutor.ExecuteFirstPass(ctx, input, sf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("failed ExecuteFirstPass: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var builtDeps []*BuiltDep
|
var builtDeps []*BuiltDep
|
||||||
|
|
||||||
if !input.opts.Clean {
|
if !input.opts.Clean {
|
||||||
var remainingVars []*types.BuildVars
|
var remainingVars []*alrsh.Package
|
||||||
for _, vars := range varsOfPackages {
|
for _, vars := range varsOfPackages {
|
||||||
builtPkgPath, ok, err := b.cacheExecutor.CheckForBuiltPackage(ctx, input, vars)
|
builtPkgPath, ok, err := b.cacheExecutor.CheckForBuiltPackage(ctx, input, vars)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -367,6 +367,7 @@ func (b *Builder) BuildPackage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
slog.Debug("ViewScript")
|
slog.Debug("ViewScript")
|
||||||
|
slog.Debug("", "varsOfPackages", varsOfPackages)
|
||||||
err = b.scriptViewerExecutor.ViewScript(ctx, input, sf, basePkg)
|
err = b.scriptViewerExecutor.ViewScript(ctx, input, sf, basePkg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -390,11 +391,11 @@ func (b *Builder) BuildPackage(
|
|||||||
sources := []string{}
|
sources := []string{}
|
||||||
checksums := []string{}
|
checksums := []string{}
|
||||||
for _, vars := range varsOfPackages {
|
for _, vars := range varsOfPackages {
|
||||||
buildDepends = append(buildDepends, vars.BuildDepends...)
|
buildDepends = append(buildDepends, vars.BuildDepends.Resolved()...)
|
||||||
optDepends = append(optDepends, vars.OptDepends...)
|
optDepends = append(optDepends, vars.OptDepends.Resolved()...)
|
||||||
depends = append(depends, vars.Depends...)
|
depends = append(depends, vars.Depends.Resolved()...)
|
||||||
sources = append(sources, vars.Sources...)
|
sources = append(sources, vars.Sources.Resolved()...)
|
||||||
checksums = append(checksums, vars.Checksums...)
|
checksums = append(checksums, vars.Checksums.Resolved()...)
|
||||||
}
|
}
|
||||||
buildDepends = removeDuplicates(buildDepends)
|
buildDepends = removeDuplicates(buildDepends)
|
||||||
optDepends = removeDuplicates(optDepends)
|
optDepends = removeDuplicates(optDepends)
|
||||||
@ -481,7 +482,7 @@ func (b *Builder) BuildPackage(
|
|||||||
|
|
||||||
type InstallPkgsArgs struct {
|
type InstallPkgsArgs struct {
|
||||||
BuildArgs
|
BuildArgs
|
||||||
AlrPkgs []db.Package
|
AlrPkgs []alrsh.Package
|
||||||
NativePkgs []string
|
NativePkgs []string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -492,7 +493,7 @@ func (b *Builder) InstallALRPackages(
|
|||||||
BuildOptsProvider
|
BuildOptsProvider
|
||||||
PkgFormatProvider
|
PkgFormatProvider
|
||||||
},
|
},
|
||||||
alrPkgs []db.Package,
|
alrPkgs []alrsh.Package,
|
||||||
) error {
|
) error {
|
||||||
for _, pkg := range alrPkgs {
|
for _, pkg := range alrPkgs {
|
||||||
res, err := b.BuildPackageFromDb(
|
res, err := b.BuildPackageFromDb(
|
||||||
@ -539,7 +540,7 @@ func (b *Builder) BuildALRDeps(
|
|||||||
|
|
||||||
found, notFound, err := b.repos.FindPkgs(ctx, depends) // Поиск зависимостей
|
found, notFound, err := b.repos.FindPkgs(ctx, depends) // Поиск зависимостей
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, fmt.Errorf("failed FindPkgs: %w", err)
|
||||||
}
|
}
|
||||||
repoDeps = notFound
|
repoDeps = notFound
|
||||||
|
|
||||||
@ -551,7 +552,7 @@ func (b *Builder) BuildALRDeps(
|
|||||||
input.BuildOpts().Interactive,
|
input.BuildOpts().Interactive,
|
||||||
)
|
)
|
||||||
type item struct {
|
type item struct {
|
||||||
pkg *db.Package
|
pkg *alrsh.Package
|
||||||
packages []string
|
packages []string
|
||||||
}
|
}
|
||||||
pkgsMap := make(map[string]*item)
|
pkgsMap := make(map[string]*item)
|
||||||
@ -586,7 +587,7 @@ func (b *Builder) BuildALRDeps(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, fmt.Errorf("failed build package from db: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
buildDeps = append(buildDeps, res...)
|
buildDeps = append(buildDeps, res...)
|
||||||
|
@ -23,7 +23,7 @@ import (
|
|||||||
|
|
||||||
"github.com/goreleaser/nfpm/v2"
|
"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 {
|
type Cache struct {
|
||||||
@ -33,7 +33,7 @@ type Cache struct {
|
|||||||
func (c *Cache) CheckForBuiltPackage(
|
func (c *Cache) CheckForBuiltPackage(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
input *BuildInput,
|
input *BuildInput,
|
||||||
vars *types.BuildVars,
|
vars *alrsh.Package,
|
||||||
) (string, bool, error) {
|
) (string, bool, error) {
|
||||||
filename, err := pkgFileName(input, vars)
|
filename, err := pkgFileName(input, vars)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -56,7 +56,7 @@ func pkgFileName(
|
|||||||
PkgFormatProvider
|
PkgFormatProvider
|
||||||
RepositoryProvider
|
RepositoryProvider
|
||||||
},
|
},
|
||||||
vars *types.BuildVars,
|
vars *alrsh.Package,
|
||||||
) (string, error) {
|
) (string, error) {
|
||||||
pkgInfo := getBasePkgInfo(vars, input)
|
pkgInfo := getBasePkgInfo(vars, input)
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ import (
|
|||||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
|
"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/cpu"
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/manager"
|
"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 {
|
type Checker struct {
|
||||||
@ -35,7 +35,7 @@ type Checker struct {
|
|||||||
func (c *Checker) PerformChecks(
|
func (c *Checker) PerformChecks(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
input *BuildInput,
|
input *BuildInput,
|
||||||
vars *types.BuildVars,
|
vars *alrsh.Package,
|
||||||
) (bool, error) {
|
) (bool, error) {
|
||||||
if !cpu.IsCompatibleWith(cpu.Arch(), vars.Architectures) { // Проверяем совместимость архитектуры
|
if !cpu.IsCompatibleWith(cpu.Arch(), vars.Architectures) { // Проверяем совместимость архитектуры
|
||||||
cont, err := cliutils.YesNoPrompt(
|
cont, err := cliutils.YesNoPrompt(
|
||||||
|
@ -29,7 +29,6 @@ import (
|
|||||||
|
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/logger"
|
"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/alrsh"
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var HandshakeConfig = plugin.HandshakeConfig{
|
var HandshakeConfig = plugin.HandshakeConfig{
|
||||||
@ -51,13 +50,13 @@ type ScriptExecutorRPCServer struct {
|
|||||||
// ReadScript
|
// ReadScript
|
||||||
//
|
//
|
||||||
|
|
||||||
func (s *ScriptExecutorRPC) ReadScript(ctx context.Context, scriptPath string) (*alrsh.ALRSh, error) {
|
func (s *ScriptExecutorRPC) ReadScript(ctx context.Context, scriptPath string) (*alrsh.ScriptFile, error) {
|
||||||
var resp *alrsh.ALRSh
|
var resp *alrsh.ScriptFile
|
||||||
err := s.client.Call("Plugin.ReadScript", scriptPath, &resp)
|
err := s.client.Call("Plugin.ReadScript", scriptPath, &resp)
|
||||||
return resp, err
|
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)
|
file, err := s.Impl.ReadScript(context.Background(), scriptPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -73,15 +72,15 @@ func (s *ScriptExecutorRPCServer) ReadScript(scriptPath string, resp *alrsh.ALRS
|
|||||||
|
|
||||||
type ExecuteFirstPassArgs struct {
|
type ExecuteFirstPassArgs struct {
|
||||||
Input *BuildInput
|
Input *BuildInput
|
||||||
Sf *alrsh.ALRSh
|
Sf *alrsh.ScriptFile
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExecuteFirstPassResp struct {
|
type ExecuteFirstPassResp struct {
|
||||||
BasePkg string
|
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
|
var resp *ExecuteFirstPassResp
|
||||||
err := s.client.Call("Plugin.ExecuteFirstPass", &ExecuteFirstPassArgs{
|
err := s.client.Call("Plugin.ExecuteFirstPass", &ExecuteFirstPassArgs{
|
||||||
Input: input,
|
Input: input,
|
||||||
@ -149,8 +148,8 @@ func (s *ScriptExecutorRPCServer) PrepareDirs(args *PrepareDirsArgs, reply *stru
|
|||||||
|
|
||||||
type ExecuteSecondPassArgs struct {
|
type ExecuteSecondPassArgs struct {
|
||||||
Input *BuildInput
|
Input *BuildInput
|
||||||
Sf *alrsh.ALRSh
|
Sf *alrsh.ScriptFile
|
||||||
VarsOfPackages []*types.BuildVars
|
VarsOfPackages []*alrsh.Package
|
||||||
RepoDeps []string
|
RepoDeps []string
|
||||||
BuiltDeps []*BuiltDep
|
BuiltDeps []*BuiltDep
|
||||||
BasePkg string
|
BasePkg string
|
||||||
@ -159,8 +158,8 @@ type ExecuteSecondPassArgs struct {
|
|||||||
func (s *ScriptExecutorRPC) ExecuteSecondPass(
|
func (s *ScriptExecutorRPC) ExecuteSecondPass(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
input *BuildInput,
|
input *BuildInput,
|
||||||
sf *alrsh.ALRSh,
|
sf *alrsh.ScriptFile,
|
||||||
varsOfPackages []*types.BuildVars,
|
varsOfPackages []*alrsh.Package,
|
||||||
repoDeps []string,
|
repoDeps []string,
|
||||||
builtDeps []*BuiltDep,
|
builtDeps []*BuiltDep,
|
||||||
basePkg string,
|
basePkg string,
|
||||||
|
@ -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)
|
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)
|
return sf.ParseBuildVars(ctx, input.info, input.packages)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,8 +86,8 @@ func (e *LocalScriptExecutor) PrepareDirs(
|
|||||||
func (e *LocalScriptExecutor) ExecuteSecondPass(
|
func (e *LocalScriptExecutor) ExecuteSecondPass(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
input *BuildInput,
|
input *BuildInput,
|
||||||
sf *alrsh.ALRSh,
|
sf *alrsh.ScriptFile,
|
||||||
varsOfPackages []*types.BuildVars,
|
varsOfPackages []*alrsh.Package,
|
||||||
repoDeps []string,
|
repoDeps []string,
|
||||||
builtDeps []*BuiltDep,
|
builtDeps []*BuiltDep,
|
||||||
basePkg string,
|
basePkg string,
|
||||||
@ -126,7 +126,7 @@ func (e *LocalScriptExecutor) ExecuteSecondPass(
|
|||||||
|
|
||||||
for _, vars := range varsOfPackages {
|
for _, vars := range varsOfPackages {
|
||||||
packageName := ""
|
packageName := ""
|
||||||
if vars.Base != "" {
|
if vars.BasePkgName != "" {
|
||||||
packageName = vars.Name
|
packageName = vars.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,24 +194,25 @@ func buildPkgMetadata(
|
|||||||
PkgFormatProvider
|
PkgFormatProvider
|
||||||
RepositoryProvider
|
RepositoryProvider
|
||||||
},
|
},
|
||||||
vars *types.BuildVars,
|
vars *alrsh.Package,
|
||||||
dirs types.Directories,
|
dirs types.Directories,
|
||||||
deps []string,
|
deps []string,
|
||||||
preferedContents *[]string,
|
preferedContents *[]string,
|
||||||
) (*nfpm.Info, error) {
|
) (*nfpm.Info, error) {
|
||||||
pkgInfo := getBasePkgInfo(vars, input)
|
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.Platform = "linux"
|
||||||
pkgInfo.Homepage = vars.Homepage
|
pkgInfo.Homepage = vars.Homepage.Resolved()
|
||||||
pkgInfo.License = strings.Join(vars.Licenses, ", ")
|
pkgInfo.License = strings.Join(vars.Licenses, ", ")
|
||||||
pkgInfo.Maintainer = vars.Maintainer
|
pkgInfo.Maintainer = vars.Maintainer.Resolved()
|
||||||
pkgInfo.Overridables = nfpm.Overridables{
|
pkgInfo.Overridables = nfpm.Overridables{
|
||||||
Conflicts: append(vars.Conflicts, vars.Name),
|
Conflicts: append(vars.Conflicts, vars.Name),
|
||||||
Replaces: vars.Replaces,
|
Replaces: vars.Replaces,
|
||||||
Provides: append(vars.Provides, vars.Name),
|
Provides: append(vars.Provides, vars.Name),
|
||||||
Depends: deps,
|
Depends: deps,
|
||||||
}
|
}
|
||||||
pkgInfo.Section = vars.Group
|
pkgInfo.Section = vars.Group.Resolved()
|
||||||
|
|
||||||
pkgFormat := input.PkgFormat()
|
pkgFormat := input.PkgFormat()
|
||||||
info := input.OSRelease()
|
info := input.OSRelease()
|
||||||
@ -224,12 +225,12 @@ func buildPkgMetadata(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if pkgFormat == "rpm" {
|
if pkgFormat == "rpm" {
|
||||||
pkgInfo.RPM.Group = vars.Group
|
pkgInfo.RPM.Group = vars.Group.Resolved()
|
||||||
|
|
||||||
if vars.Summary != "" {
|
if vars.Summary.Resolved() != "" {
|
||||||
pkgInfo.RPM.Summary = vars.Summary
|
pkgInfo.RPM.Summary = vars.Summary.Resolved()
|
||||||
} else {
|
} else {
|
||||||
lines := strings.SplitN(vars.Description, "\n", 2)
|
lines := strings.SplitN(vars.Description.Resolved(), "\n", 2)
|
||||||
pkgInfo.RPM.Summary = lines[0]
|
pkgInfo.RPM.Summary = lines[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -250,17 +251,17 @@ func buildPkgMetadata(
|
|||||||
}
|
}
|
||||||
pkgInfo.Overridables.Contents = contents
|
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)
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
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)
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
|
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ScriptResolver struct {
|
type ScriptResolver struct {
|
||||||
@ -34,7 +34,7 @@ type ScriptInfo struct {
|
|||||||
|
|
||||||
func (s *ScriptResolver) ResolveScript(
|
func (s *ScriptResolver) ResolveScript(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
pkg *db.Package,
|
pkg *alrsh.Package,
|
||||||
) *ScriptInfo {
|
) *ScriptInfo {
|
||||||
var repository, script string
|
var repository, script string
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ type ScriptViewer struct {
|
|||||||
func (s *ScriptViewer) ViewScript(
|
func (s *ScriptViewer) ViewScript(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
input *BuildInput,
|
input *BuildInput,
|
||||||
a *alrsh.ALRSh,
|
a *alrsh.ScriptFile,
|
||||||
basePkg string,
|
basePkg string,
|
||||||
) error {
|
) error {
|
||||||
return cliutils.PromptViewScript(
|
return cliutils.PromptViewScript(
|
||||||
|
@ -40,6 +40,7 @@ import (
|
|||||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cpu"
|
"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/manager"
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/overrides"
|
"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/distro"
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
|
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
|
||||||
)
|
)
|
||||||
@ -59,7 +60,7 @@ func prepareDirs(dirs types.Directories) error {
|
|||||||
|
|
||||||
// Функция buildContents создает секцию содержимого пакета, которая содержит файлы,
|
// Функция 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{}
|
contents := []*files.Content{}
|
||||||
|
|
||||||
processPath := func(path, trimmed string, prefered bool) error {
|
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"
|
fileContent.Type = "config|noreplace"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +156,7 @@ func buildContents(vars *types.BuildVars, dirs types.Directories, preferedConten
|
|||||||
|
|
||||||
var RegexpALRPackageName = regexp.MustCompile(`^(?P<package>[^+]+)\+alr-(?P<repo>.+)$`)
|
var RegexpALRPackageName = regexp.MustCompile(`^(?P<package>[^+]+)\+alr-(?P<repo>.+)$`)
|
||||||
|
|
||||||
func getBasePkgInfo(vars *types.BuildVars, input interface {
|
func getBasePkgInfo(vars *alrsh.Package, input interface {
|
||||||
RepositoryProvider
|
RepositoryProvider
|
||||||
OsInfoProvider
|
OsInfoProvider
|
||||||
},
|
},
|
||||||
@ -211,39 +212,39 @@ func createBuildEnvVars(info *distro.OSRelease, dirs types.Directories) []string
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Функция setScripts добавляет скрипты-перехватчики к метаданным пакета.
|
// Функция setScripts добавляет скрипты-перехватчики к метаданным пакета.
|
||||||
func setScripts(vars *types.BuildVars, info *nfpm.Info, scriptDir string) {
|
func setScripts(vars *alrsh.Package, info *nfpm.Info, scriptDir string) {
|
||||||
if vars.Scripts.PreInstall != "" {
|
if vars.Scripts.Resolved().PreInstall != "" {
|
||||||
info.Scripts.PreInstall = filepath.Join(scriptDir, vars.Scripts.PreInstall)
|
info.Scripts.PreInstall = filepath.Join(scriptDir, vars.Scripts.Resolved().PreInstall)
|
||||||
}
|
}
|
||||||
|
|
||||||
if vars.Scripts.PostInstall != "" {
|
if vars.Scripts.Resolved().PostInstall != "" {
|
||||||
info.Scripts.PostInstall = filepath.Join(scriptDir, vars.Scripts.PostInstall)
|
info.Scripts.PostInstall = filepath.Join(scriptDir, vars.Scripts.Resolved().PostInstall)
|
||||||
}
|
}
|
||||||
|
|
||||||
if vars.Scripts.PreRemove != "" {
|
if vars.Scripts.Resolved().PreRemove != "" {
|
||||||
info.Scripts.PreRemove = filepath.Join(scriptDir, vars.Scripts.PreRemove)
|
info.Scripts.PreRemove = filepath.Join(scriptDir, vars.Scripts.Resolved().PreRemove)
|
||||||
}
|
}
|
||||||
|
|
||||||
if vars.Scripts.PostRemove != "" {
|
if vars.Scripts.Resolved().PostRemove != "" {
|
||||||
info.Scripts.PostRemove = filepath.Join(scriptDir, vars.Scripts.PostRemove)
|
info.Scripts.PostRemove = filepath.Join(scriptDir, vars.Scripts.Resolved().PostRemove)
|
||||||
}
|
}
|
||||||
|
|
||||||
if vars.Scripts.PreUpgrade != "" {
|
if vars.Scripts.Resolved().PreUpgrade != "" {
|
||||||
info.ArchLinux.Scripts.PreUpgrade = filepath.Join(scriptDir, vars.Scripts.PreUpgrade)
|
info.ArchLinux.Scripts.PreUpgrade = filepath.Join(scriptDir, vars.Scripts.Resolved().PreUpgrade)
|
||||||
info.APK.Scripts.PreUpgrade = filepath.Join(scriptDir, vars.Scripts.PreUpgrade)
|
info.APK.Scripts.PreUpgrade = filepath.Join(scriptDir, vars.Scripts.Resolved().PreUpgrade)
|
||||||
}
|
}
|
||||||
|
|
||||||
if vars.Scripts.PostUpgrade != "" {
|
if vars.Scripts.Resolved().PostUpgrade != "" {
|
||||||
info.ArchLinux.Scripts.PostUpgrade = filepath.Join(scriptDir, vars.Scripts.PostUpgrade)
|
info.ArchLinux.Scripts.PostUpgrade = filepath.Join(scriptDir, vars.Scripts.Resolved().PostUpgrade)
|
||||||
info.APK.Scripts.PostUpgrade = filepath.Join(scriptDir, vars.Scripts.PostUpgrade)
|
info.APK.Scripts.PostUpgrade = filepath.Join(scriptDir, vars.Scripts.Resolved().PostUpgrade)
|
||||||
}
|
}
|
||||||
|
|
||||||
if vars.Scripts.PreTrans != "" {
|
if vars.Scripts.Resolved().PreTrans != "" {
|
||||||
info.RPM.Scripts.PreTrans = filepath.Join(scriptDir, vars.Scripts.PreTrans)
|
info.RPM.Scripts.PreTrans = filepath.Join(scriptDir, vars.Scripts.Resolved().PreTrans)
|
||||||
}
|
}
|
||||||
|
|
||||||
if vars.Scripts.PostTrans != "" {
|
if vars.Scripts.Resolved().PostTrans != "" {
|
||||||
info.RPM.Scripts.PostTrans = filepath.Join(scriptDir, vars.Scripts.PostTrans)
|
info.RPM.Scripts.PostTrans = filepath.Join(scriptDir, vars.Scripts.Resolved().PostTrans)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,8 +123,15 @@ func (b *AppBuilder) withRepos(enablePull, forcePull bool) *AppBuilder {
|
|||||||
|
|
||||||
cfg := b.deps.Cfg
|
cfg := b.deps.Cfg
|
||||||
db := b.deps.DB
|
db := b.deps.DB
|
||||||
if cfg == nil || db == nil {
|
info := b.deps.Info
|
||||||
b.err = errors.New("config and db are required before initializing repos")
|
|
||||||
|
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
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,8 +28,8 @@ import (
|
|||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
"github.com/leonelquinteros/gotext"
|
"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/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
|
// 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
|
// 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.
|
// 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 {
|
func FlattenPkgs(ctx context.Context, found map[string][]alrsh.Package, verb string, interactive bool) []alrsh.Package {
|
||||||
var outPkgs []db.Package
|
var outPkgs []alrsh.Package
|
||||||
for _, pkgs := range found {
|
for _, pkgs := range found {
|
||||||
if len(pkgs) > 1 && interactive {
|
if len(pkgs) > 1 && interactive {
|
||||||
choice, err := PkgPrompt(ctx, pkgs, verb, 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.
|
// 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 {
|
if !interactive {
|
||||||
return options[0], nil
|
return options[0], nil
|
||||||
}
|
}
|
||||||
@ -138,7 +138,7 @@ func PkgPrompt(ctx context.Context, options []db.Package, verb string, interacti
|
|||||||
var choice int
|
var choice int
|
||||||
err := survey.AskOne(prompt, &choice)
|
err := survey.AskOne(prompt, &choice)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return db.Package{}, err
|
return alrsh.Package{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return options[choice], nil
|
return options[choice], nil
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
"runtime/debug"
|
||||||
|
|
||||||
"github.com/leonelquinteros/gotext"
|
"github.com/leonelquinteros/gotext"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
@ -44,10 +45,12 @@ func HandleExitCoder(err error) {
|
|||||||
slog.Error(err.Error())
|
slog.Error(err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
debug.PrintStack()
|
||||||
cli.OsExiter(exitErr.ExitCode())
|
cli.OsExiter(exitErr.ExitCode())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug.PrintStack()
|
||||||
slog.Error(err.Error())
|
slog.Error(err.Error())
|
||||||
cli.OsExiter(1)
|
cli.OsExiter(1)
|
||||||
}
|
}
|
||||||
|
@ -28,32 +28,11 @@ import (
|
|||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
|
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
|
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
|
||||||
|
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
|
||||||
)
|
)
|
||||||
|
|
||||||
const CurrentVersion = 5
|
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 {
|
type Version struct {
|
||||||
Version int `xorm:"'version'"`
|
Version int `xorm:"'version'"`
|
||||||
}
|
}
|
||||||
@ -76,6 +55,8 @@ func New(config Config) *Database {
|
|||||||
func (d *Database) Connect() error {
|
func (d *Database) Connect() error {
|
||||||
dsn := d.config.GetPaths().DBPath
|
dsn := d.config.GetPaths().DBPath
|
||||||
engine, err := xorm.NewEngine("sqlite", dsn)
|
engine, err := xorm.NewEngine("sqlite", dsn)
|
||||||
|
// engine.SetLogLevel(log.LOG_DEBUG)
|
||||||
|
// engine.ShowSQL(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -87,7 +68,7 @@ func (d *Database) Init(ctx context.Context) error {
|
|||||||
if err := d.Connect(); err != nil {
|
if err := d.Connect(); err != nil {
|
||||||
return err
|
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
|
return err
|
||||||
}
|
}
|
||||||
ver, ok := d.GetVersion(ctx)
|
ver, ok := d.GetVersion(ctx)
|
||||||
@ -119,10 +100,10 @@ func (d *Database) addVersion(ver int) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Database) reset() 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)
|
session := d.engine.Context(ctx)
|
||||||
|
|
||||||
affected, err := session.Where("name = ? AND repository = ?", pkg.Name, pkg.Repository).Update(&pkg)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Database) GetPkgs(_ context.Context, where string, args ...any) ([]Package, error) {
|
func (d *Database) GetPkgs(_ context.Context, where string, args ...any) ([]alrsh.Package, error) {
|
||||||
var pkgs []Package
|
var pkgs []alrsh.Package
|
||||||
err := d.engine.Where(where, args...).Find(&pkgs)
|
err := d.engine.Where(where, args...).Find(&pkgs)
|
||||||
return pkgs, err
|
return pkgs, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Database) GetPkg(where string, args ...any) (*Package, error) {
|
func (d *Database) GetPkg(where string, args ...any) (*alrsh.Package, error) {
|
||||||
var pkg Package
|
var pkg alrsh.Package
|
||||||
has, err := d.engine.Where(where, args...).Get(&pkg)
|
has, err := d.engine.Where(where, args...).Get(&pkg)
|
||||||
if err != nil || !has {
|
if err != nil || !has {
|
||||||
return nil, err
|
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 {
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Database) IsEmpty() bool {
|
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
|
return err != nil || count == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,8 +25,11 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
|
"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/db"
|
||||||
|
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TestALRConfig struct{}
|
type TestALRConfig struct{}
|
||||||
@ -43,35 +46,38 @@ func prepareDb() *db.Database {
|
|||||||
return database
|
return database
|
||||||
}
|
}
|
||||||
|
|
||||||
var testPkg = db.Package{
|
var testPkg = alrsh.Package{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
Version: "0.0.1",
|
Version: "0.0.1",
|
||||||
Release: 1,
|
Release: 1,
|
||||||
Epoch: 2,
|
Epoch: 2,
|
||||||
Description: map[string]string{
|
Description: alrsh.OverridableFromMap(map[string]string{
|
||||||
"en": "Test package",
|
"en": "Test package",
|
||||||
"ru": "Проверочный пакет",
|
"ru": "Проверочный пакет",
|
||||||
},
|
}),
|
||||||
Homepage: map[string]string{
|
Homepage: alrsh.OverridableFromMap(map[string]string{
|
||||||
"en": "https://gitea.plemya-x.ru/xpamych/ALR",
|
"en": "https://gitea.plemya-x.ru/xpamych/ALR",
|
||||||
},
|
}),
|
||||||
Maintainer: map[string]string{
|
Maintainer: alrsh.OverridableFromMap(map[string]string{
|
||||||
"en": "Evgeniy Khramov <xpamych@yandex.ru>",
|
"en": "Evgeniy Khramov <xpamych@yandex.ru>",
|
||||||
"ru": "Евгений Храмов <xpamych@yandex.ru>",
|
"ru": "Евгений Храмов <xpamych@yandex.ru>",
|
||||||
},
|
}),
|
||||||
Architectures: []string{"arm64", "amd64"},
|
Architectures: []string{"arm64", "amd64"},
|
||||||
Licenses: []string{"GPL-3.0-or-later"},
|
Licenses: []string{"GPL-3.0-or-later"},
|
||||||
Provides: []string{"test"},
|
Provides: []string{"test"},
|
||||||
Conflicts: []string{"test"},
|
Conflicts: []string{"test"},
|
||||||
Replaces: []string{"test-old"},
|
Replaces: []string{"test-old"},
|
||||||
Depends: map[string][]string{
|
Depends: alrsh.OverridableFromMap(map[string][]string{
|
||||||
"": {"sudo"},
|
"": {"sudo"},
|
||||||
},
|
}),
|
||||||
BuildDepends: map[string][]string{
|
BuildDepends: alrsh.OverridableFromMap(map[string][]string{
|
||||||
"": {"golang"},
|
"": {"golang"},
|
||||||
"arch": {"go"},
|
"arch": {"go"},
|
||||||
},
|
}),
|
||||||
Repository: "default",
|
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) {
|
func TestInit(t *testing.T) {
|
||||||
@ -106,9 +112,7 @@ func TestInsertPackage(t *testing.T) {
|
|||||||
t.Fatalf("Expected 1 package, got %d", len(pkgs))
|
t.Fatalf("Expected 1 package, got %d", len(pkgs))
|
||||||
}
|
}
|
||||||
|
|
||||||
if !reflect.DeepEqual(testPkg, pkgs[0]) {
|
assert.Equal(t, testPkg, pkgs[0])
|
||||||
t.Errorf("Expected test package to be the same as database package")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetPkgs(t *testing.T) {
|
func TestGetPkgs(t *testing.T) {
|
||||||
|
@ -21,7 +21,6 @@ package overrides
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -29,7 +28,6 @@ import (
|
|||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cpu"
|
"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"
|
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -150,65 +148,6 @@ func (o *Opts) WithLanguageTags(langs []string) *Opts {
|
|||||||
return out
|
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) {
|
func parseLangs(langs []string, tags []language.Tag) ([]string, error) {
|
||||||
out := make([]string, len(tags)+len(langs))
|
out := make([]string, len(tags)+len(langs))
|
||||||
for i, tag := range tags {
|
for i, tag := range tags {
|
||||||
|
@ -22,11 +22,11 @@ package repos
|
|||||||
import (
|
import (
|
||||||
"context"
|
"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) {
|
func (rs *Repos) FindPkgs(ctx context.Context, pkgs []string) (map[string][]alrsh.Package, []string, error) {
|
||||||
found := map[string][]db.Package{}
|
found := map[string][]alrsh.Package{}
|
||||||
notFound := []string(nil)
|
notFound := []string(nil)
|
||||||
|
|
||||||
for _, pkgName := range pkgs {
|
for _, pkgName := range pkgs {
|
||||||
|
@ -24,8 +24,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"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/internal/repos"
|
||||||
|
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
|
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -89,31 +89,31 @@ func TestFindPkgsEmpty(t *testing.T) {
|
|||||||
e.Db,
|
e.Db,
|
||||||
)
|
)
|
||||||
|
|
||||||
err := e.Db.InsertPackage(e.Ctx, db.Package{
|
err := e.Db.InsertPackage(e.Ctx, alrsh.Package{
|
||||||
Name: "test1",
|
Name: "test1",
|
||||||
Repository: "default",
|
Repository: "default",
|
||||||
Version: "0.0.1",
|
Version: "0.0.1",
|
||||||
Release: 1,
|
Release: 1,
|
||||||
Description: map[string]string{
|
Provides: []string{""},
|
||||||
|
Description: alrsh.OverridableFromMap(map[string]string{
|
||||||
"en": "Test package 1",
|
"en": "Test package 1",
|
||||||
"ru": "Проверочный пакет 1",
|
"ru": "Проверочный пакет 1",
|
||||||
},
|
}),
|
||||||
Provides: []string{""},
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Expected no error, got %s", err)
|
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",
|
Name: "test2",
|
||||||
Repository: "default",
|
Repository: "default",
|
||||||
Version: "0.0.1",
|
Version: "0.0.1",
|
||||||
Release: 1,
|
Release: 1,
|
||||||
Description: map[string]string{
|
Provides: []string{"test"},
|
||||||
|
Description: alrsh.OverridableFromMap(map[string]string{
|
||||||
"en": "Test package 2",
|
"en": "Test package 2",
|
||||||
"ru": "Проверочный пакет 2",
|
"ru": "Проверочный пакет 2",
|
||||||
},
|
}),
|
||||||
Provides: []string{"test"},
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Expected no error, got %s", err)
|
t.Fatalf("Expected no error, got %s", err)
|
||||||
|
@ -27,6 +27,7 @@ import (
|
|||||||
|
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
|
"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/db"
|
||||||
|
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
|
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -84,10 +85,10 @@ build_deps=('golang')
|
|||||||
result, err := database.GetPkgs(ctx, "1 = 1")
|
result, err := database.GetPkgs(ctx, "1 = 1")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
pkgCount := 0
|
pkgCount := 0
|
||||||
for _, dbPkg := range result {
|
for _, pkg := range result {
|
||||||
assert.Equal(t, "foo", dbPkg.Name)
|
assert.Equal(t, "foo", pkg.Name)
|
||||||
assert.Equal(t, map[string]string{"": "main desc"}, dbPkg.Description)
|
assert.Equal(t, alrsh.OverridableFromMap(map[string]string{"": "main desc"}), pkg.Description)
|
||||||
assert.Equal(t, map[string][]string{"": {"sudo"}}, dbPkg.Depends)
|
assert.Equal(t, alrsh.OverridableFromMap(map[string][]string{"": {"sudo"}}), pkg.Depends)
|
||||||
pkgCount++
|
pkgCount++
|
||||||
}
|
}
|
||||||
assert.Equal(t, 1, pkgCount)
|
assert.Equal(t, 1, pkgCount)
|
||||||
@ -119,18 +120,18 @@ meta_buz() {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
pkgCount := 0
|
pkgCount := 0
|
||||||
for _, dbPkg := range result {
|
for _, pkg := range result {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Expected no error, got %s", err)
|
t.Errorf("Expected no error, got %s", err)
|
||||||
}
|
}
|
||||||
if dbPkg.Name == "bar" {
|
if pkg.Name == "bar" {
|
||||||
assert.Equal(t, map[string]string{"": "foo desc"}, dbPkg.Description)
|
assert.Equal(t, alrsh.OverridableFromMap(map[string]string{"": "foo desc"}), pkg.Description)
|
||||||
assert.Equal(t, map[string][]string{"": {"sudo"}}, dbPkg.Depends)
|
assert.Equal(t, alrsh.OverridableFromMap(map[string][]string{"": {"sudo"}}), pkg.Depends)
|
||||||
}
|
}
|
||||||
|
|
||||||
if dbPkg.Name == "buz" {
|
if pkg.Name == "buz" {
|
||||||
assert.Equal(t, map[string]string{"": "main desc"}, dbPkg.Description)
|
assert.Equal(t, alrsh.OverridableFromMap(map[string]string{"": "main desc"}), pkg.Description)
|
||||||
assert.Equal(t, map[string][]string{"": {"sudo", "doas"}}, dbPkg.Depends)
|
assert.Equal(t, alrsh.OverridableFromMap(map[string][]string{"": {"sudo", "doas"}}), pkg.Depends)
|
||||||
}
|
}
|
||||||
pkgCount++
|
pkgCount++
|
||||||
}
|
}
|
||||||
|
@ -18,12 +18,9 @@ package repos
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/go-git/go-git/v5"
|
"github.com/go-git/go-git/v5"
|
||||||
"github.com/go-git/go-git/v5/plumbing"
|
"github.com/go-git/go-git/v5/plumbing"
|
||||||
@ -34,9 +31,7 @@ import (
|
|||||||
"mvdan.cc/sh/v3/interp"
|
"mvdan.cc/sh/v3/interp"
|
||||||
"mvdan.cc/sh/v3/syntax"
|
"mvdan.cc/sh/v3/syntax"
|
||||||
|
|
||||||
"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/internal/parser"
|
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/decoder"
|
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
|
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
|
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
|
||||||
)
|
)
|
||||||
@ -63,149 +58,19 @@ func parseScript(
|
|||||||
syntaxParser *syntax.Parser,
|
syntaxParser *syntax.Parser,
|
||||||
runner *interp.Runner,
|
runner *interp.Runner,
|
||||||
r io.ReadCloser,
|
r io.ReadCloser,
|
||||||
) ([]*db.Package, error) {
|
) ([]*alrsh.Package, error) {
|
||||||
fl, err := syntaxParser.Parse(r, "alr.sh")
|
f, err := alrsh.ReadFromIOReader(r, "/tmp")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
_, dbPkgs, err := f.ParseBuildVars(ctx, &distro.OSRelease{}, []string{})
|
||||||
runner.Reset()
|
|
||||||
err = runner.Run(ctx, fl)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
for _, pkg := range dbPkgs {
|
||||||
d := decoder.New(&distro.OSRelease{}, runner)
|
pkg.Repository = repo.Name
|
||||||
d.Overrides = false
|
|
||||||
d.LikeDistros = false
|
|
||||||
|
|
||||||
pkgNames, err := parser.ParseNames(d)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed parsing package names: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
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) {
|
func getHeadReference(r *git.Repository) (plumbing.ReferenceName, error) {
|
||||||
|
@ -22,12 +22,11 @@ package search
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
|
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
|
||||||
database "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type PackagesProvider interface {
|
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 {
|
type Searcher struct {
|
||||||
@ -43,7 +42,7 @@ func New(pp PackagesProvider) *Searcher {
|
|||||||
func (s *Searcher) Search(
|
func (s *Searcher) Search(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
opts *SearchOptions,
|
opts *SearchOptions,
|
||||||
) ([]database.Package, error) {
|
) ([]alrsh.Package, error) {
|
||||||
where, args := opts.WhereClause()
|
where, args := opts.WhereClause()
|
||||||
packages, err := s.pp.GetPkgs(ctx, where, args...)
|
packages, err := s.pp.GetPkgs(ctx, where, args...)
|
||||||
return packages, err
|
return packages, err
|
||||||
|
@ -22,6 +22,8 @@ package decoder
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -52,7 +54,7 @@ type InvalidTypeError struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ite InvalidTypeError) Error() string {
|
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
|
// 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{
|
dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
|
||||||
WeaklyTypedInput: true,
|
WeaklyTypedInput: true,
|
||||||
|
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,
|
Result: val,
|
||||||
TagName: "sh",
|
TagName: "sh",
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
slog.Warn("err", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,7 +293,16 @@ func (d *Decoder) getVar(name string) *expand.Variable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, varName := range names {
|
for _, varName := range names {
|
||||||
val, ok := d.Runner.Vars[varName]
|
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 {
|
if ok {
|
||||||
// Resolve nameref variables
|
// Resolve nameref variables
|
||||||
_, resolved := val.Resolve(expand.FuncEnviron(func(s string) string {
|
_, resolved := val.Resolve(expand.FuncEnviron(func(s string) string {
|
||||||
@ -256,7 +315,6 @@ func (d *Decoder) getVar(name string) *expand.Variable {
|
|||||||
|
|
||||||
return &val
|
return &val
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,35 +114,35 @@ msgstr ""
|
|||||||
msgid "Error parsing os-release file"
|
msgid "Error parsing os-release file"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: info.go:41
|
#: info.go:42
|
||||||
msgid "Print information about a package"
|
msgid "Print information about a package"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: info.go:46
|
#: info.go:47
|
||||||
msgid "Show all information, not just for the current distro"
|
msgid "Show all information, not just for the current distro"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: info.go:67
|
#: info.go:68
|
||||||
msgid "Error getting packages"
|
msgid "Error getting packages"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: info.go:82
|
#: info.go:83
|
||||||
msgid "Command info expected at least 1 argument, got %d"
|
msgid "Command info expected at least 1 argument, got %d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: info.go:102
|
#: info.go:104
|
||||||
msgid "Error finding packages"
|
msgid "Error finding packages"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: info.go:116
|
#: info.go:118
|
||||||
msgid "Can't detect system language"
|
msgid "Can't detect system language"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: info.go:133
|
#: info.go:135
|
||||||
msgid "Error resolving overrides"
|
msgid "Error resolving overrides"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: info.go:141 info.go:146
|
#: info.go:144 info.go:149
|
||||||
msgid "Error encoding script variables"
|
msgid "Error encoding script variables"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -174,19 +174,19 @@ msgstr ""
|
|||||||
msgid "Error removing packages"
|
msgid "Error removing packages"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: internal/build/build.go:375
|
#: internal/build/build.go:376
|
||||||
msgid "Building package"
|
msgid "Building package"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: internal/build/build.go:404
|
#: internal/build/build.go:405
|
||||||
msgid "The checksums array must be the same length as sources"
|
msgid "The checksums array must be the same length as sources"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: internal/build/build.go:446
|
#: internal/build/build.go:447
|
||||||
msgid "Downloading sources"
|
msgid "Downloading sources"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: internal/build/build.go:538
|
#: internal/build/build.go:539
|
||||||
msgid "Installing dependencies"
|
msgid "Installing dependencies"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -224,15 +224,15 @@ msgstr ""
|
|||||||
msgid "Building package metadata"
|
msgid "Building package metadata"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: internal/build/script_executor.go:275
|
#: internal/build/script_executor.go:276
|
||||||
msgid "Executing prepare()"
|
msgid "Executing prepare()"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: internal/build/script_executor.go:284
|
#: internal/build/script_executor.go:285
|
||||||
msgid "Executing build()"
|
msgid "Executing build()"
|
||||||
msgstr ""
|
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()"
|
msgid "Executing %s()"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -244,15 +244,15 @@ msgstr ""
|
|||||||
msgid "Error initialization database"
|
msgid "Error initialization database"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: internal/cliutils/app_builder/builder.go:135
|
#: internal/cliutils/app_builder/builder.go:142
|
||||||
msgid "Error pulling repositories"
|
msgid "Error pulling repositories"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: internal/cliutils/app_builder/builder.go:152
|
#: internal/cliutils/app_builder/builder.go:159
|
||||||
msgid "Error parsing os release"
|
msgid "Error parsing os release"
|
||||||
msgstr ""
|
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"
|
msgid "Unable to detect a supported package manager on the system"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -336,17 +336,17 @@ msgstr ""
|
|||||||
msgid "OPTIONS"
|
msgid "OPTIONS"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: internal/cliutils/utils.go:69
|
#: internal/cliutils/utils.go:72
|
||||||
msgid ""
|
msgid ""
|
||||||
"This command is deprecated and would be removed in the future, use \"%s\" "
|
"This command is deprecated and would be removed in the future, use \"%s\" "
|
||||||
"instead!"
|
"instead!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: internal/db/db.go:95
|
#: internal/db/db.go:76
|
||||||
msgid "Database version mismatch; resetting"
|
msgid "Database version mismatch; resetting"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: internal/db/db.go:101
|
#: internal/db/db.go:82
|
||||||
msgid ""
|
msgid ""
|
||||||
"Database version does not exist. Run alr fix if something isn't working."
|
"Database version does not exist. Run alr fix if something isn't working."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -541,14 +541,14 @@ msgstr ""
|
|||||||
msgid "Error while executing search"
|
msgid "Error while executing search"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: upgrade.go:47
|
#: upgrade.go:48
|
||||||
msgid "Upgrade all installed packages"
|
msgid "Upgrade all installed packages"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: upgrade.go:105 upgrade.go:122
|
#: upgrade.go:106 upgrade.go:123
|
||||||
msgid "Error checking for updates"
|
msgid "Error checking for updates"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: upgrade.go:125
|
#: upgrade.go:126
|
||||||
msgid "There is nothing to do."
|
msgid "There is nothing to do."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -121,35 +121,35 @@ msgstr "Такой вспомогательной команды нет"
|
|||||||
msgid "Error parsing os-release file"
|
msgid "Error parsing os-release file"
|
||||||
msgstr "Ошибка при разборе файла выпуска операционной системы"
|
msgstr "Ошибка при разборе файла выпуска операционной системы"
|
||||||
|
|
||||||
#: info.go:41
|
#: info.go:42
|
||||||
msgid "Print information about a package"
|
msgid "Print information about a package"
|
||||||
msgstr "Отобразить информацию о пакете"
|
msgstr "Отобразить информацию о пакете"
|
||||||
|
|
||||||
#: info.go:46
|
#: info.go:47
|
||||||
msgid "Show all information, not just for the current distro"
|
msgid "Show all information, not just for the current distro"
|
||||||
msgstr "Показывать всю информацию, не только для текущего дистрибутива"
|
msgstr "Показывать всю информацию, не только для текущего дистрибутива"
|
||||||
|
|
||||||
#: info.go:67
|
#: info.go:68
|
||||||
msgid "Error getting packages"
|
msgid "Error getting packages"
|
||||||
msgstr "Ошибка при получении пакетов"
|
msgstr "Ошибка при получении пакетов"
|
||||||
|
|
||||||
#: info.go:82
|
#: info.go:83
|
||||||
msgid "Command info expected at least 1 argument, got %d"
|
msgid "Command info expected at least 1 argument, got %d"
|
||||||
msgstr "Для команды info ожидался хотя бы 1 аргумент, получено %d"
|
msgstr "Для команды info ожидался хотя бы 1 аргумент, получено %d"
|
||||||
|
|
||||||
#: info.go:102
|
#: info.go:104
|
||||||
msgid "Error finding packages"
|
msgid "Error finding packages"
|
||||||
msgstr "Ошибка при поиске пакетов"
|
msgstr "Ошибка при поиске пакетов"
|
||||||
|
|
||||||
#: info.go:116
|
#: info.go:118
|
||||||
msgid "Can't detect system language"
|
msgid "Can't detect system language"
|
||||||
msgstr "Ошибка при определении языка системы"
|
msgstr "Ошибка при определении языка системы"
|
||||||
|
|
||||||
#: info.go:133
|
#: info.go:135
|
||||||
msgid "Error resolving overrides"
|
msgid "Error resolving overrides"
|
||||||
msgstr "Ошибка устранения переорпеделений"
|
msgstr "Ошибка устранения переорпеделений"
|
||||||
|
|
||||||
#: info.go:141 info.go:146
|
#: info.go:144 info.go:149
|
||||||
msgid "Error encoding script variables"
|
msgid "Error encoding script variables"
|
||||||
msgstr "Ошибка кодирования переменных скрита"
|
msgstr "Ошибка кодирования переменных скрита"
|
||||||
|
|
||||||
@ -181,19 +181,19 @@ msgstr "Для команды remove ожидался хотя бы 1 аргум
|
|||||||
msgid "Error removing packages"
|
msgid "Error removing packages"
|
||||||
msgstr "Ошибка при удалении пакетов"
|
msgstr "Ошибка при удалении пакетов"
|
||||||
|
|
||||||
#: internal/build/build.go:375
|
#: internal/build/build.go:376
|
||||||
msgid "Building package"
|
msgid "Building package"
|
||||||
msgstr "Сборка пакета"
|
msgstr "Сборка пакета"
|
||||||
|
|
||||||
#: internal/build/build.go:404
|
#: internal/build/build.go:405
|
||||||
msgid "The checksums array must be the same length as sources"
|
msgid "The checksums array must be the same length as sources"
|
||||||
msgstr "Массив контрольных сумм должен быть той же длины, что и источники"
|
msgstr "Массив контрольных сумм должен быть той же длины, что и источники"
|
||||||
|
|
||||||
#: internal/build/build.go:446
|
#: internal/build/build.go:447
|
||||||
msgid "Downloading sources"
|
msgid "Downloading sources"
|
||||||
msgstr "Скачивание источников"
|
msgstr "Скачивание источников"
|
||||||
|
|
||||||
#: internal/build/build.go:538
|
#: internal/build/build.go:539
|
||||||
msgid "Installing dependencies"
|
msgid "Installing dependencies"
|
||||||
msgstr "Установка зависимостей"
|
msgstr "Установка зависимостей"
|
||||||
|
|
||||||
@ -235,15 +235,15 @@ msgstr ""
|
|||||||
msgid "Building package metadata"
|
msgid "Building package metadata"
|
||||||
msgstr "Сборка метаданных пакета"
|
msgstr "Сборка метаданных пакета"
|
||||||
|
|
||||||
#: internal/build/script_executor.go:275
|
#: internal/build/script_executor.go:276
|
||||||
msgid "Executing prepare()"
|
msgid "Executing prepare()"
|
||||||
msgstr "Выполнение prepare()"
|
msgstr "Выполнение prepare()"
|
||||||
|
|
||||||
#: internal/build/script_executor.go:284
|
#: internal/build/script_executor.go:285
|
||||||
msgid "Executing build()"
|
msgid "Executing build()"
|
||||||
msgstr "Выполнение 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()"
|
msgid "Executing %s()"
|
||||||
msgstr "Выполнение %s()"
|
msgstr "Выполнение %s()"
|
||||||
|
|
||||||
@ -255,15 +255,15 @@ msgstr "Ошибка при загрузке"
|
|||||||
msgid "Error initialization database"
|
msgid "Error initialization database"
|
||||||
msgstr "Ошибка инициализации базы данных"
|
msgstr "Ошибка инициализации базы данных"
|
||||||
|
|
||||||
#: internal/cliutils/app_builder/builder.go:135
|
#: internal/cliutils/app_builder/builder.go:142
|
||||||
msgid "Error pulling repositories"
|
msgid "Error pulling repositories"
|
||||||
msgstr "Ошибка при извлечении репозиториев"
|
msgstr "Ошибка при извлечении репозиториев"
|
||||||
|
|
||||||
#: internal/cliutils/app_builder/builder.go:152
|
#: internal/cliutils/app_builder/builder.go:159
|
||||||
msgid "Error parsing os release"
|
msgid "Error parsing os release"
|
||||||
msgstr "Ошибка при разборе файла выпуска операционной системы"
|
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"
|
msgid "Unable to detect a supported package manager on the system"
|
||||||
msgstr "Не удалось обнаружить поддерживаемый менеджер пакетов в системе"
|
msgstr "Не удалось обнаружить поддерживаемый менеджер пакетов в системе"
|
||||||
|
|
||||||
@ -347,7 +347,7 @@ msgstr "КАТЕГОРИЯ"
|
|||||||
msgid "OPTIONS"
|
msgid "OPTIONS"
|
||||||
msgstr "ПАРАМЕТРЫ"
|
msgstr "ПАРАМЕТРЫ"
|
||||||
|
|
||||||
#: internal/cliutils/utils.go:69
|
#: internal/cliutils/utils.go:72
|
||||||
msgid ""
|
msgid ""
|
||||||
"This command is deprecated and would be removed in the future, use \"%s\" "
|
"This command is deprecated and would be removed in the future, use \"%s\" "
|
||||||
"instead!"
|
"instead!"
|
||||||
@ -355,11 +355,11 @@ msgstr ""
|
|||||||
"Эта команда устарела и будет удалена в будущем, используйте вместо нее \"%s"
|
"Эта команда устарела и будет удалена в будущем, используйте вместо нее \"%s"
|
||||||
"\"!"
|
"\"!"
|
||||||
|
|
||||||
#: internal/db/db.go:95
|
#: internal/db/db.go:76
|
||||||
msgid "Database version mismatch; resetting"
|
msgid "Database version mismatch; resetting"
|
||||||
msgstr "Несоответствие версий базы данных; сброс настроек"
|
msgstr "Несоответствие версий базы данных; сброс настроек"
|
||||||
|
|
||||||
#: internal/db/db.go:101
|
#: internal/db/db.go:82
|
||||||
msgid ""
|
msgid ""
|
||||||
"Database version does not exist. Run alr fix if something isn't working."
|
"Database version does not exist. Run alr fix if something isn't working."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -557,15 +557,15 @@ msgstr "Иcкать по provides"
|
|||||||
msgid "Error while executing search"
|
msgid "Error while executing search"
|
||||||
msgstr "Ошибка при выполнении поиска"
|
msgstr "Ошибка при выполнении поиска"
|
||||||
|
|
||||||
#: upgrade.go:47
|
#: upgrade.go:48
|
||||||
msgid "Upgrade all installed packages"
|
msgid "Upgrade all installed packages"
|
||||||
msgstr "Обновить все установленные пакеты"
|
msgstr "Обновить все установленные пакеты"
|
||||||
|
|
||||||
#: upgrade.go:105 upgrade.go:122
|
#: upgrade.go:106 upgrade.go:123
|
||||||
msgid "Error checking for updates"
|
msgid "Error checking for updates"
|
||||||
msgstr "Ошибка при проверке обновлений"
|
msgstr "Ошибка при проверке обновлений"
|
||||||
|
|
||||||
#: upgrade.go:125
|
#: upgrade.go:126
|
||||||
msgid "There is nothing to do."
|
msgid "There is nothing to do."
|
||||||
msgstr "Здесь нечего делать."
|
msgstr "Здесь нечего делать."
|
||||||
|
|
||||||
|
6
list.go
6
list.go
@ -32,9 +32,9 @@ import (
|
|||||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/build"
|
"gitea.plemya-x.ru/Plemya-x/ALR/internal/build"
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
|
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
|
||||||
appbuilder "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils/app_builder"
|
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/manager"
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/utils"
|
"gitea.plemya-x.ru/Plemya-x/ALR/internal/utils"
|
||||||
|
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ListCmd() *cli.Command {
|
func ListCmd() *cli.Command {
|
||||||
@ -69,9 +69,9 @@ func ListCmd() *cli.Command {
|
|||||||
WithConfig().
|
WithConfig().
|
||||||
WithDB().
|
WithDB().
|
||||||
WithManager().
|
WithManager().
|
||||||
|
WithDistroInfo().
|
||||||
// autoPull only
|
// autoPull only
|
||||||
WithRepos().
|
WithRepos().
|
||||||
WithDistroInfo().
|
|
||||||
Build()
|
Build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -159,7 +159,7 @@ func ListCmd() *cli.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type packageInfo struct {
|
type packageInfo struct {
|
||||||
Package *database.Package
|
Package *alrsh.Package
|
||||||
Version string
|
Version string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ import (
|
|||||||
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
|
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ALRSh struct {
|
type ScriptFile struct {
|
||||||
file *syntax.File
|
file *syntax.File
|
||||||
path string
|
path string
|
||||||
}
|
}
|
||||||
@ -72,97 +72,134 @@ func createBuildEnvVars(info *distro.OSRelease, dirs types.Directories) []string
|
|||||||
return env
|
return env
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ALRSh) ParseBuildVars(ctx context.Context, info *distro.OSRelease, packages []string) (string, []*types.BuildVars, error) {
|
func (s *ScriptFile) ParseBuildVars(ctx context.Context, info *distro.OSRelease, packages []string) (string, []*Package, error) {
|
||||||
varsOfPackages := []*types.BuildVars{}
|
runner, err := s.createRunner(info)
|
||||||
|
|
||||||
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),
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
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 {
|
if err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
dec := decoder.New(info, runner) // Создаём новый декодер
|
if len(pkgNames.Names) == 0 {
|
||||||
|
|
||||||
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 {
|
|
||||||
return "", nil, errors.New("package name is missing")
|
return "", nil, errors.New("package name is missing")
|
||||||
}
|
}
|
||||||
|
|
||||||
var vars types.BuildVars
|
targetPackages := packages
|
||||||
|
if len(targetPackages) == 0 {
|
||||||
|
targetPackages = pkgNames.Names
|
||||||
|
}
|
||||||
|
|
||||||
if len(pkgs.Names) == 1 {
|
varsOfPackages, err := s.createPackagesForBuildVars(ctx, dec, pkgNames, targetPackages)
|
||||||
err = dec.DecodeVars(&vars)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
varsOfPackages = append(varsOfPackages, &vars)
|
|
||||||
|
|
||||||
return vars.Name, varsOfPackages, nil
|
baseName := pkgNames.BasePkgName
|
||||||
|
if len(pkgNames.Names) == 1 {
|
||||||
|
baseName = pkgNames.Names[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
var pkgNames []string
|
return baseName, varsOfPackages, nil
|
||||||
|
}
|
||||||
|
|
||||||
if len(packages) != 0 {
|
func (s *ScriptFile) createRunner(info *distro.OSRelease) (*interp.Runner, error) {
|
||||||
pkgNames = packages
|
scriptDir := filepath.Dir(s.path)
|
||||||
} else {
|
env := createBuildEnvVars(info, types.Directories{ScriptDir: scriptDir})
|
||||||
pkgNames = pkgs.Names
|
|
||||||
|
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 pkgNames {
|
for _, pkgName := range targetPackages {
|
||||||
var preVars types.BuildVarsPre
|
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)
|
funcName := fmt.Sprintf("meta_%s", pkgName)
|
||||||
meta, ok := dec.GetFuncWithSubshell(funcName)
|
meta, ok := dec.GetFuncWithSubshell(funcName)
|
||||||
if !ok {
|
if !ok {
|
||||||
return "", nil, fmt.Errorf("func %s is missing", funcName)
|
return nil, fmt.Errorf("func %s is missing", funcName)
|
||||||
}
|
}
|
||||||
r, err := meta(ctx)
|
|
||||||
|
metaRunner, err := meta(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
d := decoder.New(&distro.OSRelease{}, r)
|
|
||||||
err = d.DecodeVars(&preVars)
|
metaDecoder := decoder.New(&distro.OSRelease{}, metaRunner)
|
||||||
if err != nil {
|
|
||||||
return "", nil, err
|
var vars Package
|
||||||
|
if err := metaDecoder.DecodeVars(&vars); err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
vars := preVars.ToBuildVars()
|
|
||||||
vars.Name = pkgName
|
vars.Name = pkgName
|
||||||
vars.Base = pkgs.BasePkgName
|
vars.BasePkgName = basePkgName
|
||||||
|
|
||||||
varsOfPackages = append(varsOfPackages, &vars)
|
return &vars, nil
|
||||||
}
|
|
||||||
|
|
||||||
return pkgs.BasePkgName, varsOfPackages, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *ALRSh) Path() string {
|
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
|
return a.path
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *ALRSh) File() *syntax.File {
|
func (a *ScriptFile) File() *syntax.File {
|
||||||
return a.file
|
return a.file
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ import (
|
|||||||
"mvdan.cc/sh/v3/syntax/typedjson"
|
"mvdan.cc/sh/v3/syntax/typedjson"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *ALRSh) GobEncode() ([]byte, error) {
|
func (s *ScriptFile) GobEncode() ([]byte, error) {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
enc := gob.NewEncoder(&buf)
|
enc := gob.NewEncoder(&buf)
|
||||||
if err := enc.Encode(s.path); err != nil {
|
if err := enc.Encode(s.path); err != nil {
|
||||||
@ -41,7 +41,7 @@ func (s *ALRSh) GobEncode() ([]byte, error) {
|
|||||||
return buf.Bytes(), nil
|
return buf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ALRSh) GobDecode(data []byte) error {
|
func (s *ScriptFile) GobDecode(data []byte) error {
|
||||||
buf := bytes.NewBuffer(data)
|
buf := bytes.NewBuffer(data)
|
||||||
dec := gob.NewDecoder(buf)
|
dec := gob.NewDecoder(buf)
|
||||||
if err := dec.Decode(&s.path); err != nil {
|
if err := dec.Decode(&s.path); err != nil {
|
||||||
|
146
pkg/alrsh/overridable.go
Normal file
146
pkg/alrsh/overridable.go
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
105
pkg/alrsh/package.go
Normal file
105
pkg/alrsh/package.go
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,7 @@ package alrsh
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
@ -30,23 +31,27 @@ func (fs *localFs) Open(name string) (fs.File, error) {
|
|||||||
return os.Open(name)
|
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)
|
fl, err := fsys.Open(script)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to open alr.sh: %w", err)
|
return nil, fmt.Errorf("failed to open alr.sh: %w", err)
|
||||||
}
|
}
|
||||||
defer fl.Close()
|
defer fl.Close()
|
||||||
|
|
||||||
file, err := syntax.NewParser().Parse(fl, "alr.sh")
|
return ReadFromIOReader(fl, script)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &ALRSh{
|
|
||||||
file: file,
|
|
||||||
path: script,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReadFromLocal(script string) (*ALRSh, error) {
|
func ReadFromLocal(script string) (*ScriptFile, error) {
|
||||||
return ReadFromFS(&localFs{}, script)
|
return ReadFromFS(&localFs{}, script)
|
||||||
}
|
}
|
||||||
|
@ -24,49 +24,6 @@ type BuildOpts struct {
|
|||||||
Interactive bool
|
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 {
|
type Scripts struct {
|
||||||
PreInstall string `sh:"preinstall"`
|
PreInstall string `sh:"preinstall"`
|
||||||
PostInstall string `sh:"postinstall"`
|
PostInstall string `sh:"postinstall"`
|
||||||
|
21
search.go
21
search.go
@ -27,10 +27,10 @@ import (
|
|||||||
|
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
|
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
|
||||||
appbuilder "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils/app_builder"
|
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/overrides"
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/search"
|
"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/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/distro"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -139,27 +139,16 @@ func SearchCmd() *cli.Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, dbPkg := range packages {
|
for _, pkg := range packages {
|
||||||
var pkg any
|
alrsh.ResolvePackage(&pkg, names)
|
||||||
if !all {
|
|
||||||
pkg = overrides.ResolvePackage(&dbPkg, names)
|
|
||||||
} else {
|
|
||||||
pkg = &dbPkg
|
|
||||||
}
|
|
||||||
|
|
||||||
if tmpl != nil {
|
if tmpl != nil {
|
||||||
err = tmpl.Execute(os.Stdout, pkg)
|
err = tmpl.Execute(os.Stdout, &pkg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cliutils.FormatCliExit(gotext.Get("Error executing template"), err)
|
return cliutils.FormatCliExit(gotext.Get("Error executing template"), err)
|
||||||
}
|
}
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
} else {
|
} else {
|
||||||
switch v := pkg.(type) {
|
fmt.Println(pkg.Name)
|
||||||
case *overrides.ResolvedPackage:
|
|
||||||
fmt.Println(v.Name)
|
|
||||||
case *db.Package:
|
|
||||||
fmt.Println(v.Name)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ import (
|
|||||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/overrides"
|
"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/search"
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/utils"
|
"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/distro"
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
|
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
|
||||||
)
|
)
|
||||||
@ -130,8 +131,8 @@ func UpgradeCmd() *cli.Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func mapUptatesInfoToPackages(updates []UpdateInfo) []database.Package {
|
func mapUptatesInfoToPackages(updates []UpdateInfo) []alrsh.Package {
|
||||||
var pkgs []database.Package
|
var pkgs []alrsh.Package
|
||||||
for _, info := range updates {
|
for _, info := range updates {
|
||||||
pkgs = append(pkgs, *info.Package)
|
pkgs = append(pkgs, *info.Package)
|
||||||
}
|
}
|
||||||
@ -139,7 +140,7 @@ func mapUptatesInfoToPackages(updates []UpdateInfo) []database.Package {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type UpdateInfo struct {
|
type UpdateInfo struct {
|
||||||
Package *database.Package
|
Package *alrsh.Package
|
||||||
|
|
||||||
FromVersion string
|
FromVersion string
|
||||||
ToVersion string
|
ToVersion string
|
||||||
|
Reference in New Issue
Block a user