From 4899e203bb8911eb0a474746144128e5c5ec91d5 Mon Sep 17 00:00:00 2001 From: Maxim Slipenko Date: Sun, 6 Jul 2025 16:47:46 +0300 Subject: [PATCH] feat: allow finding packages by "{repo}/{pkg}" and "{pkg}+alr-{repo}" --- .golangci.yml | 5 +- build.go | 11 +---- e2e-tests/issue_130_install_test.go | 63 ++++++++++++++++++++++++++ internal/repos/find.go | 50 ++++++++++++-------- internal/translations/default.pot | 24 +++++----- internal/translations/po/ru/default.po | 24 +++++----- 6 files changed, 124 insertions(+), 53 deletions(-) create mode 100644 e2e-tests/issue_130_install_test.go diff --git a/.golangci.yml b/.golangci.yml index 7691d09..9ce1716 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -36,11 +36,14 @@ linters: - unused - errcheck - typecheck -# - forbidigo + - wrapcheck issues: fix: true exclude-rules: + - linters: + - wrapcheck + path-except: "internal/repos/find.go" - path: _test\.go linters: - errcheck diff --git a/build.go b/build.go index f0eb43d..166f533 100644 --- a/build.go +++ b/build.go @@ -23,7 +23,6 @@ import ( "log/slog" "os" "path/filepath" - "strings" "github.com/leonelquinteros/gotext" "github.com/urfave/cli/v2" @@ -133,15 +132,7 @@ func BuildCmd() *cli.Command { // TODO: handle multiple packages packageInput := c.String("package") - arr := strings.Split(packageInput, "/") - var packageSearch string - if len(arr) == 2 { - packageSearch = arr[1] - } else { - packageSearch = arr[0] - } - - pkgs, _, err := deps.Repos.FindPkgs(ctx, []string{packageSearch}) + pkgs, _, err := deps.Repos.FindPkgs(ctx, []string{packageInput}) if err != nil { return cliutils.FormatCliExit("failed to find pkgs", err) } diff --git a/e2e-tests/issue_130_install_test.go b/e2e-tests/issue_130_install_test.go new file mode 100644 index 0000000..6fa101d --- /dev/null +++ b/e2e-tests/issue_130_install_test.go @@ -0,0 +1,63 @@ +// 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 . + +//go:build e2e + +package e2etests_test + +import ( + "fmt" + "testing" + + "go.alt-gnome.ru/capytest" +) + +func TestE2EIssue130Install(t *testing.T) { + runMatrixSuite( + t, + "alr install {repo}/{package}", + COMMON_SYSTEMS, + func(t *testing.T, r capytest.Runner) { + t.Parallel() + defaultPrepare(t, r) + + r.Command("sudo", "alr", "in", fmt.Sprintf("%s/foo-pkg", REPO_NAME_FOR_E2E_TESTS)). + ExpectSuccess(). + Run(t) + + r.Command("sudo", "alr", "in", fmt.Sprintf("%s/bar-pkg", "NOT_REPO_NAME_FOR_E2E_TESTS")). + ExpectFailure(). + Run(t) + }, + ) + runMatrixSuite( + t, + "alr install {package}+alr-{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)). + ExpectSuccess(). + Run(t) + + r.Command("sudo", "alr", "in", fmt.Sprintf("bar-pkg+alr-%s", "NOT_REPO_NAME_FOR_E2E_TESTS")). + ExpectFailure(). + Run(t) + }, + ) +} diff --git a/internal/repos/find.go b/internal/repos/find.go index 957b3e3..388c489 100644 --- a/internal/repos/find.go +++ b/internal/repos/find.go @@ -21,44 +21,58 @@ package repos import ( "context" + "fmt" + "strings" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh" ) func (rs *Repos) FindPkgs(ctx context.Context, pkgs []string) (map[string][]alrsh.Package, []string, error) { - found := map[string][]alrsh.Package{} - notFound := []string(nil) + found := make(map[string][]alrsh.Package) + var notFound []string for _, pkgName := range pkgs { if pkgName == "" { continue } - result, err := rs.db.GetPkgs(ctx, "json_array_contains(provides, ?)", pkgName) - if err != nil { - return nil, nil, err - } + var result []alrsh.Package + var err error - added := 0 - for _, pkg := range result { - added++ - found[pkgName] = append(found[pkgName], pkg) - } + switch { + case strings.Contains(pkgName, "/"): + // repo/pkg + parts := strings.SplitN(pkgName, "/", 2) + repo := parts[0] + name := parts[1] + result, err = rs.db.GetPkgs(ctx, "name = ? AND repository = ?", name, repo) - if added == 0 { - result, err := rs.db.GetPkgs(ctx, "name LIKE ?", pkgName) + case strings.Contains(pkgName, "+alr-"): + // pkg+alr-repo + parts := strings.SplitN(pkgName, "+alr-", 2) + name := parts[0] + repo := parts[1] + result, err = rs.db.GetPkgs(ctx, "name = ? AND repository = ?", name, repo) + + default: + result, err = rs.db.GetPkgs(ctx, "json_array_contains(provides, ?)", pkgName) if err != nil { - return nil, nil, err + return nil, nil, fmt.Errorf("FindPkgs: get by provides: %w", err) } - for _, pkg := range result { - added++ - found[pkgName] = append(found[pkgName], pkg) + if len(result) == 0 { + result, err = rs.db.GetPkgs(ctx, "name LIKE ?", pkgName) } } - if added == 0 { + if err != nil { + return nil, nil, fmt.Errorf("FindPkgs: lookup for %q failed: %w", pkgName, err) + } + + if len(result) == 0 { notFound = append(notFound, pkgName) + } else { + found[pkgName] = result } } diff --git a/internal/translations/default.pot b/internal/translations/default.pot index 6e04003..354adf8 100644 --- a/internal/translations/default.pot +++ b/internal/translations/default.pot @@ -9,52 +9,52 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: build.go:42 +#: build.go:41 msgid "Build a local package" msgstr "" -#: build.go:48 +#: build.go:47 msgid "Path to the build script" msgstr "" -#: build.go:53 +#: build.go:52 msgid "Specify subpackage in script (for multi package script only)" msgstr "" -#: build.go:58 +#: build.go:57 msgid "Name of the package to build and its repo (example: default/go-bin)" msgstr "" -#: build.go:63 +#: build.go:62 msgid "" "Build package from scratch even if there's an already built package available" msgstr "" -#: build.go:73 +#: build.go:72 msgid "Error getting working directory" msgstr "" -#: build.go:118 +#: build.go:117 msgid "Cannot get absolute script path" msgstr "" -#: build.go:152 +#: build.go:143 msgid "Package not found" msgstr "" -#: build.go:165 +#: build.go:156 msgid "Nothing to build" msgstr "" -#: build.go:222 +#: build.go:213 msgid "Error building package" msgstr "" -#: build.go:229 +#: build.go:220 msgid "Error moving the package" msgstr "" -#: build.go:233 +#: build.go:224 msgid "Done" msgstr "" diff --git a/internal/translations/po/ru/default.po b/internal/translations/po/ru/default.po index 866e41d..f2c9932 100644 --- a/internal/translations/po/ru/default.po +++ b/internal/translations/po/ru/default.po @@ -16,52 +16,52 @@ msgstr "" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" "X-Generator: Gtranslator 48.0\n" -#: build.go:42 +#: build.go:41 msgid "Build a local package" msgstr "Сборка локального пакета" -#: build.go:48 +#: build.go:47 msgid "Path to the build script" msgstr "Путь к скрипту сборки" -#: build.go:53 +#: build.go:52 msgid "Specify subpackage in script (for multi package script only)" msgstr "Укажите подпакет в скрипте (только для многопакетного скрипта)" -#: build.go:58 +#: build.go:57 msgid "Name of the package to build and its repo (example: default/go-bin)" msgstr "Имя пакета для сборки и его репозиторий (пример: default/go-bin)" -#: build.go:63 +#: build.go:62 msgid "" "Build package from scratch even if there's an already built package available" msgstr "Создайте пакет с нуля, даже если уже имеется готовый пакет" -#: build.go:73 +#: build.go:72 msgid "Error getting working directory" msgstr "Ошибка при получении рабочего каталога" -#: build.go:118 +#: build.go:117 msgid "Cannot get absolute script path" msgstr "Невозможно получить абсолютный путь к скрипту" -#: build.go:152 +#: build.go:143 msgid "Package not found" msgstr "Пакет не найден" -#: build.go:165 +#: build.go:156 msgid "Nothing to build" msgstr "Нечего собирать" -#: build.go:222 +#: build.go:213 msgid "Error building package" msgstr "Ошибка при сборке пакета" -#: build.go:229 +#: build.go:220 msgid "Error moving the package" msgstr "Ошибка при перемещении пакета" -#: build.go:233 +#: build.go:224 msgid "Done" msgstr "Сделано"