From 4a616f213738d2ea8daa081c17cf0e5542bd471b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=B2=D0=B3=D0=B5=D0=BD=D0=B8=D0=B9=20=28=D0=A5?= =?UTF-8?q?=D1=80=D0=B0=D0=BC=D1=8B=D1=87=D0=AA=29=20=D0=A5=D1=80=D0=B0?= =?UTF-8?q?=D0=BC=D0=BE=D0=B2?= Date: Sun, 21 Sep 2025 16:21:23 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8?= =?UTF-8?q?=D0=BE=D0=BD=D0=B0=D0=BB=D0=B0=20=D1=81=D0=BE=D0=B7=D0=B4=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D0=B4=D0=B8=D1=80=D1=80=D0=B5=D0=BA=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=B8=D0=B9=20=D0=B4=D0=BB=D1=8F=20=D1=80=D0=B0?= =?UTF-8?q?=D0=B1=D0=BE=D1=82=D1=8B=20ALR?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- e2e-tests/issue_130_install_test.go | 6 +- internal/build/utils.go | 18 ++-- internal/build/utils_test.go | 158 ++++++++++++++++++++++++++++ internal/repos/find.go | 6 +- 4 files changed, 174 insertions(+), 14 deletions(-) create mode 100644 internal/build/utils_test.go diff --git a/e2e-tests/issue_130_install_test.go b/e2e-tests/issue_130_install_test.go index 6fa101d..5919322 100644 --- a/e2e-tests/issue_130_install_test.go +++ b/e2e-tests/issue_130_install_test.go @@ -45,17 +45,17 @@ func TestE2EIssue130Install(t *testing.T) { ) runMatrixSuite( t, - "alr install {package}+alr-{repo}", + "alr install {package}+{repo}", COMMON_SYSTEMS, func(t *testing.T, r capytest.Runner) { t.Parallel() defaultPrepare(t, r) - r.Command("sudo", "alr", "in", fmt.Sprintf("foo-pkg+alr-%s", REPO_NAME_FOR_E2E_TESTS)). + r.Command("sudo", "alr", "in", fmt.Sprintf("foo-pkg+%s", REPO_NAME_FOR_E2E_TESTS)). ExpectSuccess(). Run(t) - r.Command("sudo", "alr", "in", fmt.Sprintf("bar-pkg+alr-%s", "NOT_REPO_NAME_FOR_E2E_TESTS")). + r.Command("sudo", "alr", "in", fmt.Sprintf("bar-pkg+%s", "NOT_REPO_NAME_FOR_E2E_TESTS")). ExpectFailure(). Run(t) }, diff --git a/internal/build/utils.go b/internal/build/utils.go index d2e9ad8..e6efc75 100644 --- a/internal/build/utils.go +++ b/internal/build/utils.go @@ -56,13 +56,19 @@ func prepareDirs(dirs types.Directories) error { // Новые директории будут созданы или перезаписаны slog.Debug("Failed to remove base directory", "path", dirs.BaseDir, "error", err) } - + + // Создаем базовую директорию для пакета с setgid битом + err = utils.EnsureTempDirWithRootOwner(dirs.BaseDir, 0o2775) + if err != nil { + return err + } + // Создаем директории с правильным владельцем для /tmp/alr с setgid битом err = utils.EnsureTempDirWithRootOwner(dirs.SrcDir, 0o2775) if err != nil { return err } - + // Создаем директорию для пакетов с setgid битом return utils.EnsureTempDirWithRootOwner(dirs.PkgDir, 0o2775) } @@ -169,7 +175,7 @@ func normalizeContents(contents []*files.Content) { } } -var RegexpALRPackageName = regexp.MustCompile(`^(?P[^+]+)\+alr-(?P.+)$`) +var RegexpALRPackageName = regexp.MustCompile(`^(?P[^+]+)\+(?P.+)$`) func getBasePkgInfo(vars *alrsh.Package, input interface { RepositoryProvider @@ -177,12 +183,8 @@ func getBasePkgInfo(vars *alrsh.Package, input interface { }, ) *nfpm.Info { repo := input.Repository() - // Избегаем дублирования "alr-" префикса - if strings.HasPrefix(repo, "alr-") { - repo = repo[4:] // убираем "alr-" префикс - } return &nfpm.Info{ - Name: fmt.Sprintf("%s+alr-%s", vars.Name, repo), + Name: fmt.Sprintf("%s+%s", vars.Name, repo), Arch: cpu.Arch(), Version: vars.Version, Release: overrides.ReleasePlatformSpecific(vars.Release, input.OSRelease()), diff --git a/internal/build/utils_test.go b/internal/build/utils_test.go new file mode 100644 index 0000000..62da90c --- /dev/null +++ b/internal/build/utils_test.go @@ -0,0 +1,158 @@ +// ALR - Any Linux Repository +// Copyright (C) 2025 The ALR Authors +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +package build + +import ( + "testing" + + "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh" + "gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro" +) + +type mockInput struct { + repo string + osInfo *distro.OSRelease +} + +func (m *mockInput) Repository() string { + return m.repo +} + +func (m *mockInput) OSRelease() *distro.OSRelease { + return m.osInfo +} + +func TestGetBasePkgInfo(t *testing.T) { + tests := []struct { + name string + packageName string + repoName string + expectedName string + }{ + { + name: "обычный репозиторий", + packageName: "test-package", + repoName: "default", + expectedName: "test-package+default", + }, + { + name: "репозиторий с alr- префиксом", + packageName: "test-package", + repoName: "alr-default", + expectedName: "test-package+alr-default", + }, + { + name: "репозиторий с двойным alr- префиксом", + packageName: "test-package", + repoName: "alr-alr-repo", + expectedName: "test-package+alr-alr-repo", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + pkg := &alrsh.Package{ + Name: tt.packageName, + Version: "1.0.0", + Release: 1, + } + + input := &mockInput{ + repo: tt.repoName, + osInfo: &distro.OSRelease{ + ID: "test", + }, + } + + info := getBasePkgInfo(pkg, input) + + if info.Name != tt.expectedName { + t.Errorf("getBasePkgInfo() имя пакета = %v, ожидается %v", info.Name, tt.expectedName) + } + }) + } +} + +func TestRegexpALRPackageName(t *testing.T) { + tests := []struct { + name string + packageName string + expectedPkg string + expectedRepo string + shouldMatch bool + }{ + { + name: "новый формат - обычный репозиторий", + packageName: "test-package+default", + expectedPkg: "test-package", + expectedRepo: "default", + shouldMatch: true, + }, + { + name: "новый формат - alr-default репозиторий", + packageName: "test-package+alr-default", + expectedPkg: "test-package", + expectedRepo: "alr-default", + shouldMatch: true, + }, + { + name: "новый формат - двойной alr- префикс", + packageName: "test-package+alr-alr-repo", + expectedPkg: "test-package", + expectedRepo: "alr-alr-repo", + shouldMatch: true, + }, + { + name: "некорректный формат - без плюса", + packageName: "test-package", + shouldMatch: false, + }, + { + name: "некорректный формат - пустое имя пакета", + packageName: "+repo", + shouldMatch: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + matches := RegexpALRPackageName.FindStringSubmatch(tt.packageName) + + if tt.shouldMatch { + if matches == nil { + t.Errorf("RegexpALRPackageName должен найти совпадение для %q", tt.packageName) + return + } + + packageName := matches[RegexpALRPackageName.SubexpIndex("package")] + repoName := matches[RegexpALRPackageName.SubexpIndex("repo")] + + if packageName != tt.expectedPkg { + t.Errorf("RegexpALRPackageName извлеченное имя пакета = %v, ожидается %v", packageName, tt.expectedPkg) + } + + if repoName != tt.expectedRepo { + t.Errorf("RegexpALRPackageName извлеченное имя репозитория = %v, ожидается %v", repoName, tt.expectedRepo) + } + } else { + if matches != nil { + t.Errorf("RegexpALRPackageName не должен найти совпадение для %q", tt.packageName) + } + } + }) + } +} \ No newline at end of file diff --git a/internal/repos/find.go b/internal/repos/find.go index cb046d1..fcbf0e7 100644 --- a/internal/repos/find.go +++ b/internal/repos/find.go @@ -47,9 +47,9 @@ func (rs *Repos) FindPkgs(ctx context.Context, pkgs []string) (map[string][]alrs name := parts[1] result, err = rs.db.GetPkgs(ctx, "name = ? AND repository = ?", name, repo) - case strings.Contains(pkgName, "+alr-"): - // pkg+alr-repo - parts := strings.SplitN(pkgName, "+alr-", 2) + case strings.Contains(pkgName, "+"): + // pkg+repo + parts := strings.SplitN(pkgName, "+", 2) name := parts[0] repo := parts[1] result, err = rs.db.GetPkgs(ctx, "name = ? AND repository = ?", name, repo)