forked from Plemya-x/ALR
fix: prevent for building dependencies twice (#99)
closes #94 Reviewed-on: Plemya-x/ALR#99 Co-authored-by: Maxim Slipenko <no-reply@maxim.slipenko.com> Co-committed-by: Maxim Slipenko <no-reply@maxim.slipenko.com>
This commit is contained in:
@ -28,7 +28,6 @@ jobs:
|
|||||||
|
|
||||||
container:
|
container:
|
||||||
image: altlinux.space/maks1ms/actions-container-runner:latest
|
image: altlinux.space/maks1ms/actions-container-runner:latest
|
||||||
privileged: true
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@ -52,8 +51,6 @@ jobs:
|
|||||||
|
|
||||||
- name: Run E2E tests
|
- name: Run E2E tests
|
||||||
env:
|
env:
|
||||||
DOCKER_HOST: unix:///tmp/podman.sock
|
|
||||||
IGNORE_ROOT_CHECK: 1
|
IGNORE_ROOT_CHECK: 1
|
||||||
run: |
|
run: |
|
||||||
podman system service -t 0 unix:///tmp/podman.sock &
|
|
||||||
make e2e-test
|
make e2e-test
|
||||||
|
8
build.go
8
build.go
@ -97,7 +97,7 @@ func BuildCmd() *cli.Command {
|
|||||||
var script string
|
var script string
|
||||||
var packages []string
|
var packages []string
|
||||||
|
|
||||||
var res *build.BuildResult
|
var res []*build.BuiltDep
|
||||||
|
|
||||||
var scriptArgs *build.BuildPackageFromScriptArgs
|
var scriptArgs *build.BuildPackageFromScriptArgs
|
||||||
var dbArgs *build.BuildPackageFromDbArgs
|
var dbArgs *build.BuildPackageFromDbArgs
|
||||||
@ -222,9 +222,9 @@ func BuildCmd() *cli.Command {
|
|||||||
return cliutils.FormatCliExit(gotext.Get("Error building package"), err)
|
return cliutils.FormatCliExit(gotext.Get("Error building package"), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, pkgPath := range res.PackagePaths {
|
for _, pkg := range res {
|
||||||
name := filepath.Base(pkgPath)
|
name := filepath.Base(pkg.Path)
|
||||||
err = osutils.Move(pkgPath, filepath.Join(wd, name))
|
err = osutils.Move(pkg.Path, filepath.Join(wd, name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cliutils.FormatCliExit(gotext.Get("Error moving the package"), err)
|
return cliutils.FormatCliExit(gotext.Get("Error moving the package"), err)
|
||||||
}
|
}
|
||||||
|
49
e2e-tests/issue_94_twice_build_test.go
Normal file
49
e2e-tests/issue_94_twice_build_test.go
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// 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/>.
|
||||||
|
|
||||||
|
//go:build e2e
|
||||||
|
|
||||||
|
package e2etests_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/efficientgo/e2e"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestE2EIssue94TwiceBuild(t *testing.T) {
|
||||||
|
dockerMultipleRun(
|
||||||
|
t,
|
||||||
|
"issue-94-twice-build",
|
||||||
|
COMMON_SYSTEMS,
|
||||||
|
func(t *testing.T, r e2e.Runnable) {
|
||||||
|
defaultPrepare(t, r)
|
||||||
|
|
||||||
|
var stderr bytes.Buffer
|
||||||
|
err := r.Exec(
|
||||||
|
e2e.NewCommand("sudo", "alr", "in", "test-94-app"),
|
||||||
|
e2e.WithExecOptionStderr(&stderr),
|
||||||
|
)
|
||||||
|
assert.NoError(t, err, "command failed")
|
||||||
|
|
||||||
|
output := stderr.String()
|
||||||
|
assert.Equal(t, 1, strings.Count(output, "Building package name=test-94-dep"))
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
@ -98,7 +98,7 @@ func InstallCmd() *cli.Command {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = builder.InstallPkgs(
|
_, err = builder.InstallPkgs(
|
||||||
ctx,
|
ctx,
|
||||||
&build.BuildArgs{
|
&build.BuildArgs{
|
||||||
Opts: &types.BuildOpts{
|
Opts: &types.BuildOpts{
|
||||||
|
@ -377,19 +377,19 @@ msgstr ""
|
|||||||
msgid "Error while running app"
|
msgid "Error while running app"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pkg/build/build.go:395
|
#: pkg/build/build.go:417
|
||||||
msgid "Building package"
|
msgid "Building package"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pkg/build/build.go:424
|
#: pkg/build/build.go:446
|
||||||
msgid "The checksums array must be the same length as sources"
|
msgid "The checksums array must be the same length as sources"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pkg/build/build.go:455
|
#: pkg/build/build.go:488
|
||||||
msgid "Downloading sources"
|
msgid "Downloading sources"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pkg/build/build.go:549
|
#: pkg/build/build.go:580
|
||||||
msgid "Installing dependencies"
|
msgid "Installing dependencies"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -423,19 +423,19 @@ msgstr ""
|
|||||||
msgid "AutoReq is not implemented for this package format, so it's skipped"
|
msgid "AutoReq is not implemented for this package format, so it's skipped"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pkg/build/script_executor.go:241
|
#: pkg/build/script_executor.go:236
|
||||||
msgid "Building package metadata"
|
msgid "Building package metadata"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pkg/build/script_executor.go:372
|
#: pkg/build/script_executor.go:366
|
||||||
msgid "Executing prepare()"
|
msgid "Executing prepare()"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pkg/build/script_executor.go:381
|
#: pkg/build/script_executor.go:375
|
||||||
msgid "Executing build()"
|
msgid "Executing build()"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pkg/build/script_executor.go:410 pkg/build/script_executor.go:430
|
#: pkg/build/script_executor.go:404 pkg/build/script_executor.go:424
|
||||||
msgid "Executing %s()"
|
msgid "Executing %s()"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -12,8 +12,8 @@ msgstr ""
|
|||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
|
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||||
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||||
"X-Generator: Gtranslator 48.0\n"
|
"X-Generator: Gtranslator 48.0\n"
|
||||||
|
|
||||||
#: build.go:42
|
#: build.go:42
|
||||||
@ -290,8 +290,8 @@ 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 ""
|
||||||
"Эта команда устарела и будет удалена в будущем, используйте вместо нее "
|
"Эта команда устарела и будет удалена в будущем, используйте вместо нее \"%s"
|
||||||
"\"%s\"!"
|
"\"!"
|
||||||
|
|
||||||
#: internal/db/db.go:137
|
#: internal/db/db.go:137
|
||||||
msgid "Database version mismatch; resetting"
|
msgid "Database version mismatch; resetting"
|
||||||
@ -387,19 +387,19 @@ msgstr "Показать справку"
|
|||||||
msgid "Error while running app"
|
msgid "Error while running app"
|
||||||
msgstr "Ошибка при запуске приложения"
|
msgstr "Ошибка при запуске приложения"
|
||||||
|
|
||||||
#: pkg/build/build.go:395
|
#: pkg/build/build.go:417
|
||||||
msgid "Building package"
|
msgid "Building package"
|
||||||
msgstr "Сборка пакета"
|
msgstr "Сборка пакета"
|
||||||
|
|
||||||
#: pkg/build/build.go:424
|
#: pkg/build/build.go:446
|
||||||
msgid "The checksums array must be the same length as sources"
|
msgid "The checksums array must be the same length as sources"
|
||||||
msgstr "Массив контрольных сумм должен быть той же длины, что и источники"
|
msgstr "Массив контрольных сумм должен быть той же длины, что и источники"
|
||||||
|
|
||||||
#: pkg/build/build.go:455
|
#: pkg/build/build.go:488
|
||||||
msgid "Downloading sources"
|
msgid "Downloading sources"
|
||||||
msgstr "Скачивание источников"
|
msgstr "Скачивание источников"
|
||||||
|
|
||||||
#: pkg/build/build.go:549
|
#: pkg/build/build.go:580
|
||||||
msgid "Installing dependencies"
|
msgid "Installing dependencies"
|
||||||
msgstr "Установка зависимостей"
|
msgstr "Установка зависимостей"
|
||||||
|
|
||||||
@ -437,19 +437,19 @@ msgid "AutoReq is not implemented for this package format, so it's skipped"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"AutoReq не реализовано для этого формата пакета, поэтому будет пропущено"
|
"AutoReq не реализовано для этого формата пакета, поэтому будет пропущено"
|
||||||
|
|
||||||
#: pkg/build/script_executor.go:241
|
#: pkg/build/script_executor.go:236
|
||||||
msgid "Building package metadata"
|
msgid "Building package metadata"
|
||||||
msgstr "Сборка метаданных пакета"
|
msgstr "Сборка метаданных пакета"
|
||||||
|
|
||||||
#: pkg/build/script_executor.go:372
|
#: pkg/build/script_executor.go:366
|
||||||
msgid "Executing prepare()"
|
msgid "Executing prepare()"
|
||||||
msgstr "Выполнение prepare()"
|
msgstr "Выполнение prepare()"
|
||||||
|
|
||||||
#: pkg/build/script_executor.go:381
|
#: pkg/build/script_executor.go:375
|
||||||
msgid "Executing build()"
|
msgid "Executing build()"
|
||||||
msgstr "Выполнение build()"
|
msgstr "Выполнение build()"
|
||||||
|
|
||||||
#: pkg/build/script_executor.go:410 pkg/build/script_executor.go:430
|
#: pkg/build/script_executor.go:404 pkg/build/script_executor.go:424
|
||||||
msgid "Executing %s()"
|
msgid "Executing %s()"
|
||||||
msgstr "Выполнение %s()"
|
msgstr "Выполнение %s()"
|
||||||
|
|
||||||
|
@ -174,9 +174,29 @@ func (s *ScriptFile) GobDecode(data []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type BuildResult struct {
|
type BuiltDep struct {
|
||||||
PackagePaths []string
|
Name string
|
||||||
PackageNames []string
|
Path string
|
||||||
|
}
|
||||||
|
|
||||||
|
func Map[T, R any](items []T, f func(T) R) []R {
|
||||||
|
res := make([]R, len(items))
|
||||||
|
for i, item := range items {
|
||||||
|
res[i] = f(item)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetBuiltPaths(deps []*BuiltDep) []string {
|
||||||
|
return Map(deps, func(dep *BuiltDep) string {
|
||||||
|
return dep.Path
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetBuiltName(deps []*BuiltDep) []string {
|
||||||
|
return Map(deps, func(dep *BuiltDep) string {
|
||||||
|
return dep.Name
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type PackageFinder interface {
|
type PackageFinder interface {
|
||||||
@ -212,9 +232,9 @@ type ScriptExecutor interface {
|
|||||||
sf *ScriptFile,
|
sf *ScriptFile,
|
||||||
varsOfPackages []*types.BuildVars,
|
varsOfPackages []*types.BuildVars,
|
||||||
repoDeps []string,
|
repoDeps []string,
|
||||||
builtNames []string,
|
builtDeps []*BuiltDep,
|
||||||
basePkg string,
|
basePkg string,
|
||||||
) (*SecondPassResult, error)
|
) ([]*BuiltDep, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type CacheExecutor interface {
|
type CacheExecutor interface {
|
||||||
@ -320,7 +340,7 @@ type BuildPackageFromScriptArgs struct {
|
|||||||
func (b *Builder) BuildPackageFromDb(
|
func (b *Builder) BuildPackageFromDb(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
args *BuildPackageFromDbArgs,
|
args *BuildPackageFromDbArgs,
|
||||||
) (*BuildResult, error) {
|
) ([]*BuiltDep, error) {
|
||||||
scriptInfo := b.scriptResolver.ResolveScript(ctx, args.Package)
|
scriptInfo := b.scriptResolver.ResolveScript(ctx, args.Package)
|
||||||
|
|
||||||
return b.BuildPackage(ctx, &BuildInput{
|
return b.BuildPackage(ctx, &BuildInput{
|
||||||
@ -336,7 +356,7 @@ func (b *Builder) BuildPackageFromDb(
|
|||||||
func (b *Builder) BuildPackageFromScript(
|
func (b *Builder) BuildPackageFromScript(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
args *BuildPackageFromScriptArgs,
|
args *BuildPackageFromScriptArgs,
|
||||||
) (*BuildResult, error) {
|
) ([]*BuiltDep, error) {
|
||||||
return b.BuildPackage(ctx, &BuildInput{
|
return b.BuildPackage(ctx, &BuildInput{
|
||||||
script: args.Script,
|
script: args.Script,
|
||||||
repository: "default",
|
repository: "default",
|
||||||
@ -350,7 +370,7 @@ func (b *Builder) BuildPackageFromScript(
|
|||||||
func (b *Builder) BuildPackage(
|
func (b *Builder) BuildPackage(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
input *BuildInput,
|
input *BuildInput,
|
||||||
) (*BuildResult, error) {
|
) ([]*BuiltDep, error) {
|
||||||
scriptPath := input.script
|
scriptPath := input.script
|
||||||
|
|
||||||
slog.Debug("ReadScript")
|
slog.Debug("ReadScript")
|
||||||
@ -365,7 +385,7 @@ func (b *Builder) BuildPackage(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
builtPaths := make([]string, 0)
|
var builtDeps []*BuiltDep
|
||||||
|
|
||||||
if !input.opts.Clean {
|
if !input.opts.Clean {
|
||||||
var remainingVars []*types.BuildVars
|
var remainingVars []*types.BuildVars
|
||||||
@ -375,14 +395,16 @@ func (b *Builder) BuildPackage(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if ok {
|
if ok {
|
||||||
builtPaths = append(builtPaths, builtPkgPath)
|
builtDeps = append(builtDeps, &BuiltDep{
|
||||||
|
Path: builtPkgPath,
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
remainingVars = append(remainingVars, vars)
|
remainingVars = append(remainingVars, vars)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(remainingVars) == 0 {
|
if len(remainingVars) == 0 {
|
||||||
return &BuildResult{builtPaths, nil}, nil
|
return builtDeps, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -427,19 +449,32 @@ func (b *Builder) BuildPackage(
|
|||||||
sources, checksums = removeDuplicatesSources(sources, checksums)
|
sources, checksums = removeDuplicatesSources(sources, checksums)
|
||||||
|
|
||||||
slog.Debug("installBuildDeps")
|
slog.Debug("installBuildDeps")
|
||||||
err = b.installBuildDeps(ctx, input, buildDepends)
|
alrBuildDeps, err := b.installBuildDeps(ctx, input, buildDepends)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
slog.Debug("installOptDeps")
|
slog.Debug("installOptDeps")
|
||||||
err = b.installOptDeps(ctx, input, optDepends)
|
_, err = b.installOptDeps(ctx, input, optDepends)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
depNames := make(map[string]struct{})
|
||||||
|
for _, dep := range alrBuildDeps {
|
||||||
|
depNames[dep.Name] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We filter so as not to re-build what has already been built at the `installBuildDeps` stage.
|
||||||
|
var filteredDepends []string
|
||||||
|
for _, d := range depends {
|
||||||
|
if _, found := depNames[d]; !found {
|
||||||
|
filteredDepends = append(filteredDepends, d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
slog.Debug("BuildALRDeps")
|
slog.Debug("BuildALRDeps")
|
||||||
builtPaths, builtNames, repoDeps, err := b.BuildALRDeps(ctx, input, depends)
|
newBuiltDeps, repoDeps, err := b.BuildALRDeps(ctx, input, filteredDepends)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -450,8 +485,6 @@ func (b *Builder) BuildPackage(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// builtPaths = append(builtPaths, newBuildPaths...)
|
|
||||||
|
|
||||||
slog.Info(gotext.Get("Downloading sources"))
|
slog.Info(gotext.Get("Downloading sources"))
|
||||||
slog.Debug("DownloadSources")
|
slog.Debug("DownloadSources")
|
||||||
err = b.sourceExecutor.DownloadSources(
|
err = b.sourceExecutor.DownloadSources(
|
||||||
@ -467,6 +500,8 @@ func (b *Builder) BuildPackage(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
builtDeps = removeDuplicates(append(builtDeps, newBuiltDeps...))
|
||||||
|
|
||||||
slog.Debug("ExecuteSecondPass")
|
slog.Debug("ExecuteSecondPass")
|
||||||
res, err := b.scriptExecutor.ExecuteSecondPass(
|
res, err := b.scriptExecutor.ExecuteSecondPass(
|
||||||
ctx,
|
ctx,
|
||||||
@ -474,20 +509,16 @@ func (b *Builder) BuildPackage(
|
|||||||
sf,
|
sf,
|
||||||
varsOfPackages,
|
varsOfPackages,
|
||||||
repoDeps,
|
repoDeps,
|
||||||
builtNames,
|
builtDeps,
|
||||||
basePkg,
|
basePkg,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
pkgPaths := removeDuplicates(append(builtPaths, res.BuiltPaths...))
|
builtDeps = removeDuplicates(append(builtDeps, res...))
|
||||||
pkgNames := removeDuplicates(append(builtNames, res.BuiltNames...))
|
|
||||||
|
|
||||||
return &BuildResult{
|
return builtDeps, nil
|
||||||
PackagePaths: pkgPaths,
|
|
||||||
PackageNames: pkgNames,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type InstallPkgsArgs struct {
|
type InstallPkgsArgs struct {
|
||||||
@ -523,7 +554,7 @@ func (b *Builder) InstallALRPackages(
|
|||||||
}
|
}
|
||||||
|
|
||||||
err = b.installerExecutor.InstallLocal(
|
err = b.installerExecutor.InstallLocal(
|
||||||
res.PackagePaths,
|
GetBuiltPaths(res),
|
||||||
&manager.Opts{
|
&manager.Opts{
|
||||||
NoConfirm: !input.BuildOpts().Interactive,
|
NoConfirm: !input.BuildOpts().Interactive,
|
||||||
},
|
},
|
||||||
@ -544,13 +575,13 @@ func (b *Builder) BuildALRDeps(
|
|||||||
PkgFormatProvider
|
PkgFormatProvider
|
||||||
},
|
},
|
||||||
depends []string,
|
depends []string,
|
||||||
) (builtPaths, builtNames, repoDeps []string, err error) {
|
) (buildDeps []*BuiltDep, repoDeps []string, err error) {
|
||||||
if len(depends) > 0 {
|
if len(depends) > 0 {
|
||||||
slog.Info(gotext.Get("Installing dependencies"))
|
slog.Info(gotext.Get("Installing dependencies"))
|
||||||
|
|
||||||
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, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
repoDeps = notFound
|
repoDeps = notFound
|
||||||
|
|
||||||
@ -597,20 +628,17 @@ func (b *Builder) BuildALRDeps(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
builtPaths = append(builtPaths, res.PackagePaths...)
|
buildDeps = append(buildDeps, res...)
|
||||||
builtNames = append(builtNames, res.PackageNames...)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Удаляем возможные дубликаты, которые могут быть введены, если
|
|
||||||
// несколько зависимостей зависят от одних и тех же пакетов.
|
|
||||||
repoDeps = removeDuplicates(repoDeps)
|
repoDeps = removeDuplicates(repoDeps)
|
||||||
builtPaths = removeDuplicates(builtPaths)
|
buildDeps = removeDuplicates(buildDeps)
|
||||||
builtNames = removeDuplicates(builtNames)
|
|
||||||
return builtPaths, builtNames, repoDeps, nil
|
return buildDeps, repoDeps, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Builder) installBuildDeps(
|
func (i *Builder) installBuildDeps(
|
||||||
@ -621,19 +649,20 @@ func (i *Builder) installBuildDeps(
|
|||||||
PkgFormatProvider
|
PkgFormatProvider
|
||||||
},
|
},
|
||||||
pkgs []string,
|
pkgs []string,
|
||||||
) error {
|
) ([]*BuiltDep, error) {
|
||||||
|
var builtDeps []*BuiltDep
|
||||||
if len(pkgs) > 0 {
|
if len(pkgs) > 0 {
|
||||||
deps, err := i.installerExecutor.RemoveAlreadyInstalled(pkgs)
|
deps, err := i.installerExecutor.RemoveAlreadyInstalled(pkgs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = i.InstallPkgs(ctx, input, deps) // Устанавливаем выбранные пакеты
|
builtDeps, err = i.InstallPkgs(ctx, input, deps) // Устанавливаем выбранные пакеты
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return builtDeps, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Builder) installOptDeps(
|
func (i *Builder) installOptDeps(
|
||||||
@ -644,10 +673,11 @@ func (i *Builder) installOptDeps(
|
|||||||
PkgFormatProvider
|
PkgFormatProvider
|
||||||
},
|
},
|
||||||
pkgs []string,
|
pkgs []string,
|
||||||
) error {
|
) ([]*BuiltDep, error) {
|
||||||
|
var builtDeps []*BuiltDep
|
||||||
optDeps, err := i.installerExecutor.RemoveAlreadyInstalled(pkgs)
|
optDeps, err := i.installerExecutor.RemoveAlreadyInstalled(pkgs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(optDeps) > 0 {
|
if len(optDeps) > 0 {
|
||||||
optDeps, err := cliutils.ChooseOptDepends(
|
optDeps, err := cliutils.ChooseOptDepends(
|
||||||
@ -657,19 +687,19 @@ func (i *Builder) installOptDeps(
|
|||||||
input.BuildOpts().Interactive,
|
input.BuildOpts().Interactive,
|
||||||
) // Пользователя просят выбрать опциональные зависимости
|
) // Пользователя просят выбрать опциональные зависимости
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(optDeps) == 0 {
|
if len(optDeps) == 0 {
|
||||||
return nil
|
return builtDeps, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
err = i.InstallPkgs(ctx, input, optDeps) // Устанавливаем выбранные пакеты
|
builtDeps, err = i.InstallPkgs(ctx, input, optDeps) // Устанавливаем выбранные пакеты
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return builtDeps, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Builder) InstallPkgs(
|
func (i *Builder) InstallPkgs(
|
||||||
@ -680,18 +710,18 @@ func (i *Builder) InstallPkgs(
|
|||||||
PkgFormatProvider
|
PkgFormatProvider
|
||||||
},
|
},
|
||||||
pkgs []string,
|
pkgs []string,
|
||||||
) error {
|
) ([]*BuiltDep, error) {
|
||||||
builtPaths, _, repoDeps, err := i.BuildALRDeps(ctx, input, pkgs)
|
builtDeps, repoDeps, err := i.BuildALRDeps(ctx, input, pkgs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(builtPaths) > 0 {
|
if len(builtDeps) > 0 {
|
||||||
err = i.installerExecutor.InstallLocal(builtPaths, &manager.Opts{
|
err = i.installerExecutor.InstallLocal(GetBuiltPaths(builtDeps), &manager.Opts{
|
||||||
NoConfirm: !input.BuildOpts().Interactive,
|
NoConfirm: !input.BuildOpts().Interactive,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -700,9 +730,9 @@ func (i *Builder) InstallPkgs(
|
|||||||
NoConfirm: !input.BuildOpts().Interactive,
|
NoConfirm: !input.BuildOpts().Interactive,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return builtDeps, nil
|
||||||
}
|
}
|
||||||
|
@ -151,7 +151,7 @@ type ExecuteSecondPassArgs struct {
|
|||||||
Sf *ScriptFile
|
Sf *ScriptFile
|
||||||
VarsOfPackages []*types.BuildVars
|
VarsOfPackages []*types.BuildVars
|
||||||
RepoDeps []string
|
RepoDeps []string
|
||||||
BuiltNames []string
|
BuiltDeps []*BuiltDep
|
||||||
BasePkg string
|
BasePkg string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,16 +161,16 @@ func (s *ScriptExecutorRPC) ExecuteSecondPass(
|
|||||||
sf *ScriptFile,
|
sf *ScriptFile,
|
||||||
varsOfPackages []*types.BuildVars,
|
varsOfPackages []*types.BuildVars,
|
||||||
repoDeps []string,
|
repoDeps []string,
|
||||||
builtNames []string,
|
builtDeps []*BuiltDep,
|
||||||
basePkg string,
|
basePkg string,
|
||||||
) (*SecondPassResult, error) {
|
) ([]*BuiltDep, error) {
|
||||||
var resp *SecondPassResult
|
var resp []*BuiltDep
|
||||||
err := s.client.Call("Plugin.ExecuteSecondPass", &ExecuteSecondPassArgs{
|
err := s.client.Call("Plugin.ExecuteSecondPass", &ExecuteSecondPassArgs{
|
||||||
Input: input,
|
Input: input,
|
||||||
Sf: sf,
|
Sf: sf,
|
||||||
VarsOfPackages: varsOfPackages,
|
VarsOfPackages: varsOfPackages,
|
||||||
RepoDeps: repoDeps,
|
RepoDeps: repoDeps,
|
||||||
BuiltNames: builtNames,
|
BuiltDeps: builtDeps,
|
||||||
BasePkg: basePkg,
|
BasePkg: basePkg,
|
||||||
}, &resp)
|
}, &resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -179,20 +179,20 @@ func (s *ScriptExecutorRPC) ExecuteSecondPass(
|
|||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ScriptExecutorRPCServer) ExecuteSecondPass(args *ExecuteSecondPassArgs, resp *SecondPassResult) error {
|
func (s *ScriptExecutorRPCServer) ExecuteSecondPass(args *ExecuteSecondPassArgs, resp *[]*BuiltDep) error {
|
||||||
res, err := s.Impl.ExecuteSecondPass(
|
res, err := s.Impl.ExecuteSecondPass(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
args.Input,
|
args.Input,
|
||||||
args.Sf,
|
args.Sf,
|
||||||
args.VarsOfPackages,
|
args.VarsOfPackages,
|
||||||
args.RepoDeps,
|
args.RepoDeps,
|
||||||
args.BuiltNames,
|
args.BuiltDeps,
|
||||||
args.BasePkg,
|
args.BasePkg,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
*resp = *res
|
*resp = res
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,11 +152,6 @@ func (e *LocalScriptExecutor) ExecuteFirstPass(ctx context.Context, input *Build
|
|||||||
return pkgs.BasePkgName, varsOfPackages, nil
|
return pkgs.BasePkgName, varsOfPackages, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type SecondPassResult struct {
|
|
||||||
BuiltPaths []string
|
|
||||||
BuiltNames []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *LocalScriptExecutor) PrepareDirs(
|
func (e *LocalScriptExecutor) PrepareDirs(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
input *BuildInput,
|
input *BuildInput,
|
||||||
@ -185,9 +180,9 @@ func (e *LocalScriptExecutor) ExecuteSecondPass(
|
|||||||
sf *ScriptFile,
|
sf *ScriptFile,
|
||||||
varsOfPackages []*types.BuildVars,
|
varsOfPackages []*types.BuildVars,
|
||||||
repoDeps []string,
|
repoDeps []string,
|
||||||
builtNames []string,
|
builtDeps []*BuiltDep,
|
||||||
basePkg string,
|
basePkg string,
|
||||||
) (*SecondPassResult, error) {
|
) ([]*BuiltDep, error) {
|
||||||
dirs, err := getDirs(e.cfg, sf.Path, basePkg)
|
dirs, err := getDirs(e.cfg, sf.Path, basePkg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -213,7 +208,7 @@ func (e *LocalScriptExecutor) ExecuteSecondPass(
|
|||||||
|
|
||||||
dec := decoder.New(input.info, runner)
|
dec := decoder.New(input.info, runner)
|
||||||
|
|
||||||
var builtPaths []string
|
// var builtPaths []string
|
||||||
|
|
||||||
err = e.ExecuteFunctions(ctx, dirs, dec)
|
err = e.ExecuteFunctions(ctx, dirs, dec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -247,7 +242,7 @@ func (e *LocalScriptExecutor) ExecuteSecondPass(
|
|||||||
dirs,
|
dirs,
|
||||||
append(
|
append(
|
||||||
repoDeps,
|
repoDeps,
|
||||||
builtNames...,
|
GetBuiltName(builtDeps)...,
|
||||||
),
|
),
|
||||||
funcOut.Contents,
|
funcOut.Contents,
|
||||||
)
|
)
|
||||||
@ -273,14 +268,13 @@ func (e *LocalScriptExecutor) ExecuteSecondPass(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
builtPaths = append(builtPaths, pkgPath)
|
builtDeps = append(builtDeps, &BuiltDep{
|
||||||
builtNames = append(builtNames, vars.Name)
|
Name: vars.Name,
|
||||||
|
Path: pkgPath,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return &SecondPassResult{
|
return builtDeps, nil
|
||||||
BuiltPaths: builtPaths,
|
|
||||||
BuiltNames: builtNames,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildPkgMetadata(
|
func buildPkgMetadata(
|
||||||
|
@ -288,14 +288,14 @@ func packageNames(pkgs []db.Package) []string {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Функция removeDuplicates убирает любые дубликаты из предоставленного среза.
|
// Функция removeDuplicates убирает любые дубликаты из предоставленного среза.
|
||||||
func removeDuplicates(slice []string) []string {
|
func removeDuplicates[T comparable](slice []T) []T {
|
||||||
seen := map[string]struct{}{}
|
seen := map[T]struct{}{}
|
||||||
result := []string{}
|
result := []T{}
|
||||||
|
|
||||||
for _, s := range slice {
|
for _, item := range slice {
|
||||||
if _, ok := seen[s]; !ok {
|
if _, ok := seen[item]; !ok {
|
||||||
seen[s] = struct{}{}
|
seen[item] = struct{}{}
|
||||||
result = append(result, s)
|
result = append(result, item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user