feat: add skiplists for auto_req and auto_prov #64
| @@ -11,7 +11,7 @@ | ||||
|     <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="14">coverage</text> | ||||
|         <text x="86" y="15" fill="#010101" fill-opacity=".3">19.4%</text> | ||||
|         <text x="86" y="14">19.4%</text> | ||||
|         <text x="86" y="15" fill="#010101" fill-opacity=".3">19.2%</text> | ||||
|         <text x="86" y="14">19.2%</text> | ||||
|     </g> | ||||
| </svg> | ||||
|   | ||||
| Before Width: | Height: | Size: 926 B After Width: | Height: | Size: 926 B | 
| @@ -100,13 +100,19 @@ func e2eSpawn(runnable e2e.Runnable, command e2e.Command, timeout time.Duration, | ||||
|  | ||||
| var ALL_SYSTEMS []string = []string{ | ||||
| 	"ubuntu-24.04", | ||||
| 	// "alt-sisyphus", | ||||
| 	"alt-sisyphus", | ||||
| 	"fedora-41", | ||||
| 	// "archlinux", | ||||
| 	// "alpine", | ||||
| 	// "opensuse-leap", | ||||
| 	// "redos-8", | ||||
| } | ||||
|  | ||||
| var AUTOREQ_AUTOPROV_SYSTEMS []string = []string{ | ||||
| 	"alt-sisyphus", | ||||
| 	"fedora-41", | ||||
| } | ||||
|  | ||||
| var COMMON_SYSTEMS []string = []string{ | ||||
| 	"ubuntu-24.04", | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| FROM registry.altlinux.org/sisyphus/alt:latest | ||||
| RUN apt-get update && apt-get install -y ca-certificates | ||||
| RUN apt-get update && apt-get install -y ca-certificates rpm-build | ||||
| RUN useradd -m -s /bin/bash alr-user | ||||
| USER alr-user | ||||
| WORKDIR /home/alr-user | ||||
| ENTRYPOINT ["tail", "-f", "/dev/null"] | ||||
							
								
								
									
										8
									
								
								e2e-tests/images/Dockerfile.fedora-41
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								e2e-tests/images/Dockerfile.fedora-41
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| FROM fedora:41 | ||||
| RUN dnf install -y ca-certificates sudo rpm-build | ||||
| RUN useradd -m -s /bin/bash alr-user && \ | ||||
|     echo "alr-user ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/alr-user && \ | ||||
|     chmod 0440 /etc/sudoers.d/alr-user | ||||
| USER alr-user | ||||
| WORKDIR /home/alr-user | ||||
| ENTRYPOINT ["tail", "-f", "/dev/null"] | ||||
							
								
								
									
										80
									
								
								e2e-tests/issue_41_autoreq_skiplist_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								e2e-tests/issue_41_autoreq_skiplist_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | ||||
| // ALR - Any Linux Repository | ||||
| // Copyright (C) 2025 Евгений Храмов | ||||
| // | ||||
| // 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 ( | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/alecthomas/assert/v2" | ||||
| 	"github.com/efficientgo/e2e" | ||||
| ) | ||||
|  | ||||
| func TestE2EIssue41AutoreqSkiplist(t *testing.T) { | ||||
| 	dockerMultipleRun( | ||||
| 		t, | ||||
| 		"issue-41-autoreq-skiplist", | ||||
| 		AUTOREQ_AUTOPROV_SYSTEMS, | ||||
| 		func(t *testing.T, r e2e.Runnable) { | ||||
| 			err := r.Exec(e2e.NewCommand( | ||||
| 				"alr", | ||||
| 				"addrepo", | ||||
| 				"--name", | ||||
| 				"alr-repo", | ||||
| 				"--url", | ||||
| 				"https://gitea.plemya-x.ru/Maks1mS/repo-for-tests.git", | ||||
| 			)) | ||||
| 			assert.NoError(t, err) | ||||
|  | ||||
| 			err = r.Exec(e2e.NewCommand( | ||||
| 				"alr", | ||||
| 				"ref", | ||||
| 			)) | ||||
| 			assert.NoError(t, err) | ||||
|  | ||||
| 			err = r.Exec(e2e.NewCommand( | ||||
| 				"alr", | ||||
| 				"build", | ||||
| 				"-p", | ||||
| 				"alr-repo/test-autoreq-autoprov", | ||||
| 			)) | ||||
| 			assert.NoError(t, err) | ||||
|  | ||||
| 			err = r.Exec(e2e.NewCommand( | ||||
| 				"sh", | ||||
| 				"-c", | ||||
| 				"rpm -qp --requires *.rpm | grep \"^/bin/sh$\"", | ||||
| 			)) | ||||
| 			assert.NoError(t, err) | ||||
|  | ||||
| 			err = r.Exec(e2e.NewCommand( | ||||
| 				"sh", | ||||
| 				"-c", | ||||
| 				"rpm -qp --requires *.rpm | grep \"^/bin/bash$\"", | ||||
| 			)) | ||||
| 			assert.Error(t, err) | ||||
|  | ||||
| 			err = r.Exec(e2e.NewCommand( | ||||
| 				"sh", | ||||
| 				"-c", | ||||
| 				"rpm -qp --requires *.rpm | grep \"^/bin/zsh$\"", | ||||
| 			)) | ||||
| 			assert.Error(t, err) | ||||
| 		}, | ||||
| 	) | ||||
| } | ||||
| @@ -123,15 +123,29 @@ func (d *Decoder) DecodeVars(val any) error { | ||||
| 	} | ||||
|  | ||||
| 	rVal := reflect.ValueOf(val).Elem() | ||||
| 	return d.decodeStruct(rVal) | ||||
| } | ||||
|  | ||||
| func (d *Decoder) decodeStruct(rVal reflect.Value) error { | ||||
| 	for i := 0; i < rVal.NumField(); i++ { | ||||
| 		field := rVal.Field(i) | ||||
| 		fieldType := rVal.Type().Field(i) | ||||
|  | ||||
| 		// Пропускаем неэкспортируемые поля | ||||
| 		if !fieldType.IsExported() { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		// Обрабатываем встроенные поля рекурсивно | ||||
| 		if fieldType.Anonymous { | ||||
| 			if field.Kind() == reflect.Struct { | ||||
| 				if err := d.decodeStruct(field); err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 			} | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		name := fieldType.Name | ||||
| 		tag := fieldType.Tag.Get("sh") | ||||
| 		required := false | ||||
| @@ -160,7 +174,6 @@ func (d *Decoder) DecodeVars(val any) error { | ||||
|  | ||||
| 		field.Set(newVal.Elem()) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -337,92 +337,92 @@ msgstr "" | ||||
| msgid "Error while running app" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:156 | ||||
| #: pkg/build/build.go:157 | ||||
| msgid "Failed to prompt user to view build script" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:160 | ||||
| #: pkg/build/build.go:161 | ||||
| msgid "Building package" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:208 | ||||
| #: pkg/build/build.go:209 | ||||
| msgid "The checksums array must be the same length as sources" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:235 | ||||
| #: pkg/build/build.go:238 | ||||
| msgid "Downloading sources" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:257 | ||||
| #: pkg/build/build.go:260 | ||||
| msgid "Building package metadata" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:279 | ||||
| #: pkg/build/build.go:282 | ||||
| msgid "Compressing package" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:438 | ||||
| #: pkg/build/build.go:441 | ||||
| msgid "" | ||||
| "Your system's CPU architecture doesn't match this package. Do you want to " | ||||
| "build anyway?" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:452 | ||||
| #: pkg/build/build.go:455 | ||||
| msgid "This package is already installed" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:476 | ||||
| #: pkg/build/build.go:479 | ||||
| msgid "Installing build dependencies" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:521 | ||||
| #: pkg/build/build.go:524 | ||||
| msgid "Installing dependencies" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:602 | ||||
| #: pkg/build/build.go:605 | ||||
| msgid "Would you like to remove the build dependencies?" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:665 | ||||
| #: pkg/build/build.go:668 | ||||
| msgid "Executing prepare()" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:675 | ||||
| #: pkg/build/build.go:678 | ||||
| msgid "Executing build()" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:705 pkg/build/build.go:725 | ||||
| #: pkg/build/build.go:708 pkg/build/build.go:728 | ||||
| msgid "Executing %s()" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:784 | ||||
| #: pkg/build/build.go:787 | ||||
| msgid "Error installing native packages" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:808 | ||||
| #: pkg/build/build.go:811 | ||||
| msgid "Error installing package" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:867 | ||||
| msgid "AutoProv is not implemented for this package format, so it's skipped" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:878 | ||||
| msgid "AutoReq is not implemented for this package format, so it's skipped" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/findDeps.go:35 | ||||
| #: pkg/build/find_deps/alt_linux.go:35 | ||||
| msgid "Command not found on the system" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/findDeps.go:82 | ||||
| #: pkg/build/find_deps/alt_linux.go:86 | ||||
| msgid "Provided dependency found" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/findDeps.go:89 | ||||
| #: pkg/build/find_deps/alt_linux.go:93 | ||||
| msgid "Required dependency found" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/find_deps/empty.go:32 | ||||
| msgid "AutoProv is not implemented for this package format, so it's skipped" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/find_deps/empty.go:37 | ||||
| msgid "AutoReq is not implemented for this package format, so it's skipped" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/repos/pull.go:79 | ||||
| msgid "Pulling repository" | ||||
| msgstr "" | ||||
|   | ||||
| @@ -349,31 +349,31 @@ msgstr "Показать справку" | ||||
| msgid "Error while running app" | ||||
| msgstr "Ошибка при запуске приложения" | ||||
|  | ||||
| #: pkg/build/build.go:156 | ||||
| #: pkg/build/build.go:157 | ||||
| msgid "Failed to prompt user to view build script" | ||||
| msgstr "Не удалось предложить пользователю просмотреть скрипт сборки" | ||||
|  | ||||
| #: pkg/build/build.go:160 | ||||
| #: pkg/build/build.go:161 | ||||
| msgid "Building package" | ||||
| msgstr "Сборка пакета" | ||||
|  | ||||
| #: pkg/build/build.go:208 | ||||
| #: pkg/build/build.go:209 | ||||
| msgid "The checksums array must be the same length as sources" | ||||
| msgstr "Массив контрольных сумм должен быть той же длины, что и источники" | ||||
|  | ||||
| #: pkg/build/build.go:235 | ||||
| #: pkg/build/build.go:238 | ||||
| msgid "Downloading sources" | ||||
| msgstr "Скачивание источников" | ||||
|  | ||||
| #: pkg/build/build.go:257 | ||||
| #: pkg/build/build.go:260 | ||||
| msgid "Building package metadata" | ||||
| msgstr "Сборка метаданных пакета" | ||||
|  | ||||
| #: pkg/build/build.go:279 | ||||
| #: pkg/build/build.go:282 | ||||
| msgid "Compressing package" | ||||
| msgstr "Сжатие пакета" | ||||
|  | ||||
| #: pkg/build/build.go:438 | ||||
| #: pkg/build/build.go:441 | ||||
| msgid "" | ||||
| "Your system's CPU architecture doesn't match this package. Do you want to " | ||||
| "build anyway?" | ||||
| @@ -381,64 +381,64 @@ msgstr "" | ||||
| "Архитектура процессора вашей системы не соответствует этому пакету. Вы все " | ||||
| "равно хотите выполнить сборку?" | ||||
|  | ||||
| #: pkg/build/build.go:452 | ||||
| #: pkg/build/build.go:455 | ||||
| msgid "This package is already installed" | ||||
| msgstr "Этот пакет уже установлен" | ||||
|  | ||||
| #: pkg/build/build.go:476 | ||||
| #: pkg/build/build.go:479 | ||||
| msgid "Installing build dependencies" | ||||
| msgstr "Установка зависимостей сборки" | ||||
|  | ||||
| #: pkg/build/build.go:521 | ||||
| #: pkg/build/build.go:524 | ||||
| msgid "Installing dependencies" | ||||
| msgstr "Установка зависимостей" | ||||
|  | ||||
| #: pkg/build/build.go:602 | ||||
| #: pkg/build/build.go:605 | ||||
| msgid "Would you like to remove the build dependencies?" | ||||
| msgstr "Хотели бы вы удалить зависимости сборки?" | ||||
|  | ||||
| #: pkg/build/build.go:665 | ||||
| #: pkg/build/build.go:668 | ||||
| msgid "Executing prepare()" | ||||
| msgstr "Исполнение prepare()" | ||||
|  | ||||
| #: pkg/build/build.go:675 | ||||
| #: pkg/build/build.go:678 | ||||
| msgid "Executing build()" | ||||
| msgstr "Исполнение build()" | ||||
|  | ||||
| #: pkg/build/build.go:705 pkg/build/build.go:725 | ||||
| #: pkg/build/build.go:708 pkg/build/build.go:728 | ||||
| msgid "Executing %s()" | ||||
| msgstr "Исполнение %s()" | ||||
|  | ||||
| #: pkg/build/build.go:784 | ||||
| #: pkg/build/build.go:787 | ||||
| msgid "Error installing native packages" | ||||
| msgstr "Ошибка при установке нативных пакетов" | ||||
|  | ||||
| #: pkg/build/build.go:808 | ||||
| #: pkg/build/build.go:811 | ||||
| msgid "Error installing package" | ||||
| msgstr "Ошибка при установке пакета" | ||||
|  | ||||
| #: pkg/build/build.go:867 | ||||
| #: pkg/build/find_deps/alt_linux.go:35 | ||||
| msgid "Command not found on the system" | ||||
| msgstr "Команда не найдена в системе" | ||||
|  | ||||
| #: pkg/build/find_deps/alt_linux.go:86 | ||||
| msgid "Provided dependency found" | ||||
| msgstr "Найденная предоставленная зависимость" | ||||
|  | ||||
| #: pkg/build/find_deps/alt_linux.go:93 | ||||
| msgid "Required dependency found" | ||||
| msgstr "Найдена требуемая зависимость" | ||||
|  | ||||
| #: pkg/build/find_deps/empty.go:32 | ||||
| msgid "AutoProv is not implemented for this package format, so it's skipped" | ||||
| msgstr "" | ||||
| "AutoProv не реализовано для этого формата пакета, поэтому будет пропущено" | ||||
|  | ||||
| #: pkg/build/build.go:878 | ||||
| #: pkg/build/find_deps/empty.go:37 | ||||
| msgid "AutoReq is not implemented for this package format, so it's skipped" | ||||
| msgstr "" | ||||
| "AutoReq не реализовано для этого формата пакета, поэтому будет пропущено" | ||||
|  | ||||
| #: pkg/build/findDeps.go:35 | ||||
| msgid "Command not found on the system" | ||||
| msgstr "Команда не найдена в системе" | ||||
|  | ||||
| #: pkg/build/findDeps.go:82 | ||||
| msgid "Provided dependency found" | ||||
| msgstr "Найденная предоставленная зависимость" | ||||
|  | ||||
| #: pkg/build/findDeps.go:89 | ||||
| msgid "Required dependency found" | ||||
| msgstr "Найдена требуемая зависимость" | ||||
|  | ||||
| #: pkg/repos/pull.go:79 | ||||
| msgid "Pulling repository" | ||||
| msgstr "Скачивание репозитория" | ||||
|   | ||||
| @@ -31,79 +31,44 @@ type BuildOpts struct { | ||||
| } | ||||
|  | ||||
| type BuildVarsPre struct { | ||||
| 	Version       string   `sh:"version,required"` | ||||
| 	Release       int      `sh:"release,required"` | ||||
| 	Epoch         uint     `sh:"epoch"` | ||||
| 	Description   string   `sh:"desc"` | ||||
| 	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"` | ||||
| 	Version          string   `sh:"version,required"` | ||||
| 	Release          int      `sh:"release,required"` | ||||
| 	Epoch            uint     `sh:"epoch"` | ||||
| 	Description      string   `sh:"desc"` | ||||
| 	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:          "", | ||||
| 		Version:       bv.Version, | ||||
| 		Release:       bv.Release, | ||||
| 		Epoch:         bv.Epoch, | ||||
| 		Description:   bv.Description, | ||||
| 		Homepage:      bv.Homepage, | ||||
| 		Maintainer:    bv.Maintainer, | ||||
| 		Architectures: bv.Architectures, | ||||
| 		Licenses:      bv.Licenses, | ||||
| 		Provides:      bv.Provides, | ||||
| 		Conflicts:     bv.Conflicts, | ||||
| 		Depends:       bv.Depends, | ||||
| 		BuildDepends:  bv.BuildDepends, | ||||
| 		OptDepends:    bv.OptDepends, | ||||
| 		Replaces:      bv.Replaces, | ||||
| 		Sources:       bv.Sources, | ||||
| 		Checksums:     bv.Checksums, | ||||
| 		Backup:        bv.Backup, | ||||
| 		Scripts:       bv.Scripts, | ||||
| 		AutoReq:       bv.AutoReq, | ||||
| 		AutoProv:      bv.AutoProv, | ||||
| 		Name:         "", | ||||
| 		Base:         "", | ||||
| 		BuildVarsPre: *bv, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // BuildVars represents the script variables required | ||||
| // to build a package | ||||
| type BuildVars struct { | ||||
| 	Name          string   `sh:"name,required"` | ||||
| 	Version       string   `sh:"version,required"` | ||||
| 	Release       int      `sh:"release,required"` | ||||
| 	Epoch         uint     `sh:"epoch"` | ||||
| 	Description   string   `sh:"desc"` | ||||
| 	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"` | ||||
| 	Base          string | ||||
| 	Name string `sh:"name,required"` | ||||
| 	Base string | ||||
| 	BuildVarsPre | ||||
| } | ||||
|  | ||||
| type Scripts struct { | ||||
|   | ||||
| @@ -50,6 +50,7 @@ import ( | ||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/handlers" | ||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/helpers" | ||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" | ||||
| 	finddeps "gitea.plemya-x.ru/Plemya-x/ALR/pkg/build/find_deps" | ||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro" | ||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/pkg/manager" | ||||
| ) | ||||
| @@ -211,8 +212,10 @@ func (b *Builder) BuildPackage(ctx context.Context) ([]string, []string, error) | ||||
| 	sources, checksums = removeDuplicatesSources(sources, checksums) | ||||
|  | ||||
| 	mergedVars := types.BuildVars{ | ||||
| 		Sources:   sources, | ||||
| 		Checksums: checksums, | ||||
| 		BuildVarsPre: types.BuildVarsPre{ | ||||
| 			Sources:   sources, | ||||
| 			Checksums: checksums, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	buildDeps, err := b.installBuildDeps(ctx, buildDepends) // Устанавливаем зависимости для сборки | ||||
| @@ -858,24 +861,18 @@ func (b *Builder) buildPkgMetadata( | ||||
| 	pkgInfo.Overridables.Contents = contents | ||||
|  | ||||
| 	if len(vars.AutoProv) == 1 && decoder.IsTruthy(vars.AutoProv[0]) { | ||||
| 		if pkgFormat == "rpm" { | ||||
| 			err = rpmFindProvides(ctx, pkgInfo, dirs) | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 		} else { | ||||
| 			slog.Info(gotext.Get("AutoProv is not implemented for this package format, so it's skipped")) | ||||
| 		f := finddeps.New(b.info, pkgFormat) | ||||
| 		err = f.FindProvides(ctx, pkgInfo, dirs, vars.AutoProvSkipList) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if len(vars.AutoReq) == 1 && decoder.IsTruthy(vars.AutoReq[0]) { | ||||
| 		if pkgFormat == "rpm" { | ||||
| 			err = rpmFindRequires(ctx, pkgInfo, dirs) | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 		} else { | ||||
| 			slog.Info(gotext.Get("AutoReq is not implemented for this package format, so it's skipped")) | ||||
| 		f := finddeps.New(b.info, pkgFormat) | ||||
| 		err = f.FindRequires(ctx, pkgInfo, dirs, vars.AutoReqSkipList) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -14,7 +14,7 @@ | ||||
| // 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 build | ||||
| package finddeps | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| @@ -30,7 +30,7 @@ import ( | ||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" | ||||
| ) | ||||
| 
 | ||||
| func rpmFindDependencies(ctx context.Context, pkgInfo *nfpm.Info, dirs types.Directories, command string, updateFunc func(string)) error { | ||||
| func rpmFindDependenciesALTLinux(ctx context.Context, pkgInfo *nfpm.Info, dirs types.Directories, command string, envs []string, updateFunc func(string)) error { | ||||
| 	if _, err := exec.LookPath(command); err != nil { | ||||
| 		slog.Info(gotext.Get("Command not found on the system"), "command", command) | ||||
| 		return nil | ||||
| @@ -49,8 +49,8 @@ func rpmFindDependencies(ctx context.Context, pkgInfo *nfpm.Info, dirs types.Dir | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	cmd := exec.Command(command) | ||||
| 	cmd.Stdin = bytes.NewBufferString(strings.Join(paths, "\n")) | ||||
| 	cmd := exec.CommandContext(ctx, command) | ||||
| 	cmd.Stdin = bytes.NewBufferString(strings.Join(paths, "\n") + "\n") | ||||
| 	cmd.Env = append(cmd.Env, | ||||
| 		"RPM_BUILD_ROOT="+dirs.PkgDir, | ||||
| 		"RPM_FINDPROV_METHOD=", | ||||
| @@ -58,6 +58,7 @@ func rpmFindDependencies(ctx context.Context, pkgInfo *nfpm.Info, dirs types.Dir | ||||
| 		"RPM_DATADIR=", | ||||
| 		"RPM_SUBPACKAGE_NAME=", | ||||
| 	) | ||||
| 	cmd.Env = append(cmd.Env, envs...) | ||||
| 	var out bytes.Buffer | ||||
| 	var stderr bytes.Buffer | ||||
| 	cmd.Stdout = &out | ||||
| @@ -66,6 +67,7 @@ func rpmFindDependencies(ctx context.Context, pkgInfo *nfpm.Info, dirs types.Dir | ||||
| 		slog.Error(stderr.String()) | ||||
| 		return err | ||||
| 	} | ||||
| 	slog.Debug(stderr.String()) | ||||
| 
 | ||||
| 	dependencies := strings.Split(strings.TrimSpace(out.String()), "\n") | ||||
| 	for _, dep := range dependencies { | ||||
| @@ -77,15 +79,17 @@ func rpmFindDependencies(ctx context.Context, pkgInfo *nfpm.Info, dirs types.Dir | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func rpmFindProvides(ctx context.Context, pkgInfo *nfpm.Info, dirs types.Directories) error { | ||||
| 	return rpmFindDependencies(ctx, pkgInfo, dirs, "/usr/lib/rpm/find-provides", func(dep string) { | ||||
| type ALTLinuxFindProvReq struct{} | ||||
| 
 | ||||
| func (o *ALTLinuxFindProvReq) FindProvides(ctx context.Context, pkgInfo *nfpm.Info, dirs types.Directories, skiplist []string) error { | ||||
| 	return rpmFindDependenciesALTLinux(ctx, pkgInfo, dirs, "/usr/lib/rpm/find-provides", []string{"RPM_FINDPROV_SKIPLIST=" + strings.Join(skiplist, "\n")}, func(dep string) { | ||||
| 		slog.Info(gotext.Get("Provided dependency found"), "dep", dep) | ||||
| 		pkgInfo.Overridables.Provides = append(pkgInfo.Overridables.Provides, dep) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func rpmFindRequires(ctx context.Context, pkgInfo *nfpm.Info, dirs types.Directories) error { | ||||
| 	return rpmFindDependencies(ctx, pkgInfo, dirs, "/usr/lib/rpm/find-requires", func(dep string) { | ||||
| func (o *ALTLinuxFindProvReq) FindRequires(ctx context.Context, pkgInfo *nfpm.Info, dirs types.Directories, skiplist []string) error { | ||||
| 	return rpmFindDependenciesALTLinux(ctx, pkgInfo, dirs, "/usr/lib/rpm/find-requires", []string{"RPM_FINDREQ_SKIPLIST=" + strings.Join(skiplist, "\n")}, func(dep string) { | ||||
| 		slog.Info(gotext.Get("Required dependency found"), "dep", dep) | ||||
| 		pkgInfo.Overridables.Depends = append(pkgInfo.Overridables.Depends, dep) | ||||
| 	}) | ||||
							
								
								
									
										39
									
								
								pkg/build/find_deps/empty.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								pkg/build/find_deps/empty.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| // ALR - Any Linux Repository | ||||
| // Copyright (C) 2025 Евгений Храмов | ||||
| // | ||||
| // 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 finddeps | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"log/slog" | ||||
|  | ||||
| 	"github.com/goreleaser/nfpm/v2" | ||||
| 	"github.com/leonelquinteros/gotext" | ||||
|  | ||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" | ||||
| ) | ||||
|  | ||||
| type EmptyFindProvReq struct{} | ||||
|  | ||||
| func (o *EmptyFindProvReq) FindProvides(ctx context.Context, pkgInfo *nfpm.Info, dirs types.Directories, skiplist []string) error { | ||||
| 	slog.Info(gotext.Get("AutoProv is not implemented for this package format, so it's skipped")) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (o *EmptyFindProvReq) FindRequires(ctx context.Context, pkgInfo *nfpm.Info, dirs types.Directories, skiplist []string) error { | ||||
| 	slog.Info(gotext.Get("AutoReq is not implemented for this package format, so it's skipped")) | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										118
									
								
								pkg/build/find_deps/fedora.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								pkg/build/find_deps/fedora.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,118 @@ | ||||
| // ALR - Any Linux Repository | ||||
| // Copyright (C) 2025 Евгений Храмов | ||||
| // | ||||
| // 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 finddeps | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"log/slog" | ||||
| 	"os/exec" | ||||
| 	"path" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/goreleaser/nfpm/v2" | ||||
| 	"github.com/leonelquinteros/gotext" | ||||
|  | ||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" | ||||
| ) | ||||
|  | ||||
| type FedoraFindProvReq struct{} | ||||
|  | ||||
| func rpmFindDependenciesFedora(ctx context.Context, pkgInfo *nfpm.Info, dirs types.Directories, command string, args []string, updateFunc func(string)) error { | ||||
| 	if _, err := exec.LookPath(command); err != nil { | ||||
| 		slog.Info(gotext.Get("Command not found on the system"), "command", command) | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	var paths []string | ||||
| 	for _, content := range pkgInfo.Contents { | ||||
| 		if content.Type != "dir" { | ||||
| 			paths = append(paths, | ||||
| 				path.Join(dirs.PkgDir, content.Destination), | ||||
| 			) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if len(paths) == 0 { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	cmd := exec.CommandContext(ctx, command, args...) | ||||
| 	cmd.Stdin = bytes.NewBufferString(strings.Join(paths, "\n") + "\n") | ||||
| 	cmd.Env = append(cmd.Env, | ||||
| 		"RPM_BUILD_ROOT="+dirs.PkgDir, | ||||
| 	) | ||||
| 	var out bytes.Buffer | ||||
| 	var stderr bytes.Buffer | ||||
| 	cmd.Stdout = &out | ||||
| 	cmd.Stderr = &stderr | ||||
| 	if err := cmd.Run(); err != nil { | ||||
| 		slog.Error(stderr.String()) | ||||
| 		return err | ||||
| 	} | ||||
| 	slog.Debug(stderr.String()) | ||||
|  | ||||
| 	dependencies := strings.Split(strings.TrimSpace(out.String()), "\n") | ||||
| 	for _, dep := range dependencies { | ||||
| 		if dep != "" { | ||||
| 			updateFunc(dep) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (o *FedoraFindProvReq) FindProvides(ctx context.Context, pkgInfo *nfpm.Info, dirs types.Directories, skiplist []string) error { | ||||
| 	return rpmFindDependenciesFedora( | ||||
| 		ctx, | ||||
| 		pkgInfo, | ||||
| 		dirs, | ||||
| 		"/usr/lib/rpm/rpmdeps", | ||||
| 		[]string{ | ||||
| 			"--define=_use_internal_dependency_generator 1", | ||||
| 			"--provides", | ||||
| 			fmt.Sprintf( | ||||
| 				"--define=__provides_exclude_from %s\"", | ||||
| 				strings.Join(skiplist, "|"), | ||||
| 			), | ||||
| 		}, | ||||
| 		func(dep string) { | ||||
| 			slog.Info(gotext.Get("Provided dependency found"), "dep", dep) | ||||
| 			pkgInfo.Overridables.Provides = append(pkgInfo.Overridables.Provides, dep) | ||||
| 		}) | ||||
| } | ||||
|  | ||||
| func (o *FedoraFindProvReq) FindRequires(ctx context.Context, pkgInfo *nfpm.Info, dirs types.Directories, skiplist []string) error { | ||||
| 	return rpmFindDependenciesFedora( | ||||
| 		ctx, | ||||
| 		pkgInfo, | ||||
| 		dirs, | ||||
| 		"/usr/lib/rpm/rpmdeps", | ||||
| 		[]string{ | ||||
| 			"--define=_use_internal_dependency_generator 1", | ||||
| 			"--requires", | ||||
| 			fmt.Sprintf( | ||||
| 				"--define=__requires_exclude_from %s", | ||||
| 				strings.Join(skiplist, "|"), | ||||
| 			), | ||||
| 		}, | ||||
| 		func(dep string) { | ||||
| 			slog.Info(gotext.Get("Required dependency found"), "dep", dep) | ||||
| 			pkgInfo.Overridables.Depends = append(pkgInfo.Overridables.Depends, dep) | ||||
| 		}) | ||||
| } | ||||
							
								
								
									
										58
									
								
								pkg/build/find_deps/find_deps.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								pkg/build/find_deps/find_deps.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,58 @@ | ||||
| // ALR - Any Linux Repository | ||||
| // Copyright (C) 2025 Евгений Храмов | ||||
| // | ||||
| // 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 finddeps | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
|  | ||||
| 	"github.com/goreleaser/nfpm/v2" | ||||
|  | ||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" | ||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro" | ||||
| ) | ||||
|  | ||||
| type ProvReqFinder interface { | ||||
| 	FindProvides(ctx context.Context, pkgInfo *nfpm.Info, dirs types.Directories, skiplist []string) error | ||||
| 	FindRequires(ctx context.Context, pkgInfo *nfpm.Info, dirs types.Directories, skiplist []string) error | ||||
| } | ||||
|  | ||||
| type ProvReqService struct { | ||||
| 	finder ProvReqFinder | ||||
| } | ||||
|  | ||||
| func New(info *distro.OSRelease, pkgFormat string) *ProvReqService { | ||||
| 	s := &ProvReqService{ | ||||
| 		finder: &EmptyFindProvReq{}, | ||||
| 	} | ||||
| 	if pkgFormat == "rpm" { | ||||
| 		switch info.ID { | ||||
| 		case "altlinux": | ||||
| 			s.finder = &ALTLinuxFindProvReq{} | ||||
| 		case "fedora": | ||||
| 			s.finder = &FedoraFindProvReq{} | ||||
| 		} | ||||
| 	} | ||||
| 	return s | ||||
| } | ||||
|  | ||||
| func (s *ProvReqService) FindProvides(ctx context.Context, pkgInfo *nfpm.Info, dirs types.Directories, skiplist []string) error { | ||||
| 	return s.finder.FindProvides(ctx, pkgInfo, dirs, skiplist) | ||||
| } | ||||
|  | ||||
| func (s *ProvReqService) FindRequires(ctx context.Context, pkgInfo *nfpm.Info, dirs types.Directories, skiplist []string) error { | ||||
| 	return s.finder.FindRequires(ctx, pkgInfo, dirs, skiplist) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user