fix: prevent for building dependencies twice
This commit is contained in:
		
							
								
								
									
										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) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -41,7 +41,7 @@ func TestFindPkgs(t *testing.T) { | |||||||
| 	err := rs.Pull(e.Ctx, []types.Repo{ | 	err := rs.Pull(e.Ctx, []types.Repo{ | ||||||
| 		{ | 		{ | ||||||
| 			Name: "default", | 			Name: "default", | ||||||
| 			URL:  "https://gitea.plemya-x.ru/xpamych/xpamych-alr-repo.git", | 			URL:  "https://gitea.plemya-x.ru/Plemya-x/alr-default.git", | ||||||
| 		}, | 		}, | ||||||
| 	}) | 	}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user