feat: allow finding packages by "{repo}/{pkg}" and "{pkg}+alr-{repo}"
This commit is contained in:
		| @@ -36,11 +36,14 @@ linters: | |||||||
|     - unused |     - unused | ||||||
|     - errcheck |     - errcheck | ||||||
|     - typecheck |     - typecheck | ||||||
| #    - forbidigo |     - wrapcheck | ||||||
|  |  | ||||||
| issues: | issues: | ||||||
|   fix: true |   fix: true | ||||||
|   exclude-rules: |   exclude-rules: | ||||||
|  |     - linters: | ||||||
|  |         - wrapcheck | ||||||
|  |       path-except: "internal/repos/find.go" | ||||||
|     - path: _test\.go |     - path: _test\.go | ||||||
|       linters: |       linters: | ||||||
|         - errcheck |         - errcheck | ||||||
|   | |||||||
							
								
								
									
										11
									
								
								build.go
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								build.go
									
									
									
									
									
								
							| @@ -23,7 +23,6 @@ import ( | |||||||
| 	"log/slog" | 	"log/slog" | ||||||
| 	"os" | 	"os" | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| 	"strings" |  | ||||||
|  |  | ||||||
| 	"github.com/leonelquinteros/gotext" | 	"github.com/leonelquinteros/gotext" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v2" | ||||||
| @@ -133,15 +132,7 @@ func BuildCmd() *cli.Command { | |||||||
| 				// TODO: handle multiple packages | 				// TODO: handle multiple packages | ||||||
| 				packageInput := c.String("package") | 				packageInput := c.String("package") | ||||||
|  |  | ||||||
| 				arr := strings.Split(packageInput, "/") | 				pkgs, _, err := deps.Repos.FindPkgs(ctx, []string{packageInput}) | ||||||
| 				var packageSearch string |  | ||||||
| 				if len(arr) == 2 { |  | ||||||
| 					packageSearch = arr[1] |  | ||||||
| 				} else { |  | ||||||
| 					packageSearch = arr[0] |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				pkgs, _, err := deps.Repos.FindPkgs(ctx, []string{packageSearch}) |  | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					return cliutils.FormatCliExit("failed to find pkgs", err) | 					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 ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
|  | 	"fmt" | ||||||
|  | 	"strings" | ||||||
|  |  | ||||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh" | 	"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func (rs *Repos) FindPkgs(ctx context.Context, pkgs []string) (map[string][]alrsh.Package, []string, error) { | func (rs *Repos) FindPkgs(ctx context.Context, pkgs []string) (map[string][]alrsh.Package, []string, error) { | ||||||
| 	found := map[string][]alrsh.Package{} | 	found := make(map[string][]alrsh.Package) | ||||||
| 	notFound := []string(nil) | 	var notFound []string | ||||||
|  |  | ||||||
| 	for _, pkgName := range pkgs { | 	for _, pkgName := range pkgs { | ||||||
| 		if pkgName == "" { | 		if pkgName == "" { | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		result, err := rs.db.GetPkgs(ctx, "json_array_contains(provides, ?)", pkgName) | 		var result []alrsh.Package | ||||||
| 		if err != nil { | 		var err error | ||||||
| 			return nil, nil, err |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		added := 0 | 		switch { | ||||||
| 		for _, pkg := range result { | 		case strings.Contains(pkgName, "/"): | ||||||
| 			added++ | 			// repo/pkg | ||||||
| 			found[pkgName] = append(found[pkgName], 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 { | 		case strings.Contains(pkgName, "+alr-"): | ||||||
| 			result, err := rs.db.GetPkgs(ctx, "name LIKE ?", pkgName) | 			// 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 { | 			if err != nil { | ||||||
| 				return nil, nil, err | 				return nil, nil, fmt.Errorf("FindPkgs: get by provides: %w", err) | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			for _, pkg := range result { | 			if len(result) == 0 { | ||||||
| 				added++ | 				result, err = rs.db.GetPkgs(ctx, "name LIKE ?", pkgName) | ||||||
| 				found[pkgName] = append(found[pkgName], pkg) |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		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) | 			notFound = append(notFound, pkgName) | ||||||
|  | 		} else { | ||||||
|  | 			found[pkgName] = result | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -9,52 +9,52 @@ msgstr "" | |||||||
| "Content-Transfer-Encoding: 8bit\n" | "Content-Transfer-Encoding: 8bit\n" | ||||||
| "Plural-Forms: nplurals=2; plural=(n != 1);\n" | "Plural-Forms: nplurals=2; plural=(n != 1);\n" | ||||||
|  |  | ||||||
| #: build.go:42 | #: build.go:41 | ||||||
| msgid "Build a local package" | msgid "Build a local package" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: build.go:48 | #: build.go:47 | ||||||
| msgid "Path to the build script" | msgid "Path to the build script" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: build.go:53 | #: build.go:52 | ||||||
| msgid "Specify subpackage in script (for multi package script only)" | msgid "Specify subpackage in script (for multi package script only)" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: build.go:58 | #: build.go:57 | ||||||
| msgid "Name of the package to build and its repo (example: default/go-bin)" | msgid "Name of the package to build and its repo (example: default/go-bin)" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: build.go:63 | #: build.go:62 | ||||||
| msgid "" | msgid "" | ||||||
| "Build package from scratch even if there's an already built package available" | "Build package from scratch even if there's an already built package available" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: build.go:73 | #: build.go:72 | ||||||
| msgid "Error getting working directory" | msgid "Error getting working directory" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: build.go:118 | #: build.go:117 | ||||||
| msgid "Cannot get absolute script path" | msgid "Cannot get absolute script path" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: build.go:152 | #: build.go:143 | ||||||
| msgid "Package not found" | msgid "Package not found" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: build.go:165 | #: build.go:156 | ||||||
| msgid "Nothing to build" | msgid "Nothing to build" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: build.go:222 | #: build.go:213 | ||||||
| msgid "Error building package" | msgid "Error building package" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: build.go:229 | #: build.go:220 | ||||||
| msgid "Error moving the package" | msgid "Error moving the package" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: build.go:233 | #: build.go:224 | ||||||
| msgid "Done" | msgid "Done" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -16,52 +16,52 @@ msgstr "" | |||||||
| "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" | "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" | ||||||
| "X-Generator: Gtranslator 48.0\n" | "X-Generator: Gtranslator 48.0\n" | ||||||
|  |  | ||||||
| #: build.go:42 | #: build.go:41 | ||||||
| msgid "Build a local package" | msgid "Build a local package" | ||||||
| msgstr "Сборка локального пакета" | msgstr "Сборка локального пакета" | ||||||
|  |  | ||||||
| #: build.go:48 | #: build.go:47 | ||||||
| msgid "Path to the build script" | msgid "Path to the build script" | ||||||
| msgstr "Путь к скрипту сборки" | msgstr "Путь к скрипту сборки" | ||||||
|  |  | ||||||
| #: build.go:53 | #: build.go:52 | ||||||
| msgid "Specify subpackage in script (for multi package script only)" | msgid "Specify subpackage in script (for multi package script only)" | ||||||
| msgstr "Укажите подпакет в скрипте (только для многопакетного скрипта)" | msgstr "Укажите подпакет в скрипте (только для многопакетного скрипта)" | ||||||
|  |  | ||||||
| #: build.go:58 | #: build.go:57 | ||||||
| msgid "Name of the package to build and its repo (example: default/go-bin)" | msgid "Name of the package to build and its repo (example: default/go-bin)" | ||||||
| msgstr "Имя пакета для сборки и его репозиторий (пример: default/go-bin)" | msgstr "Имя пакета для сборки и его репозиторий (пример: default/go-bin)" | ||||||
|  |  | ||||||
| #: build.go:63 | #: build.go:62 | ||||||
| msgid "" | msgid "" | ||||||
| "Build package from scratch even if there's an already built package available" | "Build package from scratch even if there's an already built package available" | ||||||
| msgstr "Создайте пакет с нуля, даже если уже имеется готовый пакет" | msgstr "Создайте пакет с нуля, даже если уже имеется готовый пакет" | ||||||
|  |  | ||||||
| #: build.go:73 | #: build.go:72 | ||||||
| msgid "Error getting working directory" | msgid "Error getting working directory" | ||||||
| msgstr "Ошибка при получении рабочего каталога" | msgstr "Ошибка при получении рабочего каталога" | ||||||
|  |  | ||||||
| #: build.go:118 | #: build.go:117 | ||||||
| msgid "Cannot get absolute script path" | msgid "Cannot get absolute script path" | ||||||
| msgstr "Невозможно получить абсолютный путь к скрипту" | msgstr "Невозможно получить абсолютный путь к скрипту" | ||||||
|  |  | ||||||
| #: build.go:152 | #: build.go:143 | ||||||
| msgid "Package not found" | msgid "Package not found" | ||||||
| msgstr "Пакет не найден" | msgstr "Пакет не найден" | ||||||
|  |  | ||||||
| #: build.go:165 | #: build.go:156 | ||||||
| msgid "Nothing to build" | msgid "Nothing to build" | ||||||
| msgstr "Нечего собирать" | msgstr "Нечего собирать" | ||||||
|  |  | ||||||
| #: build.go:222 | #: build.go:213 | ||||||
| msgid "Error building package" | msgid "Error building package" | ||||||
| msgstr "Ошибка при сборке пакета" | msgstr "Ошибка при сборке пакета" | ||||||
|  |  | ||||||
| #: build.go:229 | #: build.go:220 | ||||||
| msgid "Error moving the package" | msgid "Error moving the package" | ||||||
| msgstr "Ошибка при перемещении пакета" | msgstr "Ошибка при перемещении пакета" | ||||||
|  |  | ||||||
| #: build.go:233 | #: build.go:224 | ||||||
| msgid "Done" | msgid "Done" | ||||||
| msgstr "Сделано" | msgstr "Сделано" | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user