feat: allow finding packages by "{repo}/{pkg}" and "{pkg}+alr-{repo}"

This commit is contained in:
2025-07-06 16:47:46 +03:00
parent 67a6cb31de
commit 4899e203bb
6 changed files with 124 additions and 53 deletions

View File

@ -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

View File

@ -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)
}

View File

@ -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 <http://www.gnu.org/licenses/>.
//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)
},
)
}

View File

@ -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
}
}

View File

@ -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 ""

View File

@ -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 "Сделано"