feat: allow finding packages by "{repo}/{pkg}" and "{pkg}+alr-{repo}" #133
| @@ -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 | ||||
|   | ||||
							
								
								
									
										11
									
								
								build.go
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								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) | ||||
| 				} | ||||
|   | ||||
							
								
								
									
										63
									
								
								e2e-tests/issue_130_install_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								e2e-tests/issue_130_install_test.go
									
									
									
									
									
										Normal 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) | ||||
| 		}, | ||||
| 	) | ||||
| } | ||||
| @@ -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 | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -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 "" | ||||
|  | ||||
|   | ||||
| @@ -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 "Сделано" | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user