diff --git a/assets/coverage-badge.svg b/assets/coverage-badge.svg
index e1e8356..259d4b3 100644
--- a/assets/coverage-badge.svg
+++ b/assets/coverage-badge.svg
@@ -11,7 +11,7 @@
coverage
coverage
- 18.8%
- 18.8%
+ 18.9%
+ 18.9%
diff --git a/e2e-tests/__snapshots__/TestE2EIssue62List_issue-62-list_ubuntu-24.04_1.snap.stdout b/e2e-tests/__snapshots__/TestE2EIssue62List_issue-62-list_ubuntu-24.04_1.snap.stdout
new file mode 100755
index 0000000..ea3e759
--- /dev/null
+++ b/e2e-tests/__snapshots__/TestE2EIssue62List_issue-62-list_ubuntu-24.04_1.snap.stdout
@@ -0,0 +1 @@
+alr-repo/foo-pkg 1.0.0-1
diff --git a/e2e-tests/__snapshots__/TestE2EIssue62List_issue-62-list_ubuntu-24.04_2.snap.stdout b/e2e-tests/__snapshots__/TestE2EIssue62List_issue-62-list_ubuntu-24.04_2.snap.stdout
new file mode 100755
index 0000000..b77de02
--- /dev/null
+++ b/e2e-tests/__snapshots__/TestE2EIssue62List_issue-62-list_ubuntu-24.04_2.snap.stdout
@@ -0,0 +1,2 @@
+alr-repo/bar-pkg 1.0.0-1
+alr-repo/foo-pkg 1.0.0-1
diff --git a/e2e-tests/issue_62_list_test.go b/e2e-tests/issue_62_list_test.go
new file mode 100644
index 0000000..797247a
--- /dev/null
+++ b/e2e-tests/issue_62_list_test.go
@@ -0,0 +1,50 @@
+// 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 (
+ "testing"
+
+ "go.alt-gnome.ru/capytest"
+)
+
+func TestE2EIssue62List(t *testing.T) {
+ runMatrixSuite(
+ t,
+ "issue-62-list",
+ COMMON_SYSTEMS,
+ func(t *testing.T, r capytest.Runner) {
+ defaultPrepare(t, r)
+ execShouldNoError(t, r, "sudo", "alr", "repo", "set-ref", "alr-repo", "bd26236cd7")
+ execShouldNoError(t, r, "alr", "ref")
+
+ execShouldNoError(t, r, "sudo", "alr", "in", "foo-pkg")
+
+ r.Command("alr", "list", "-I").
+ ExpectSuccess().
+ ExpectStdoutMatchesSnapshot().
+ Run(t)
+
+ r.Command("alr", "list").
+ ExpectSuccess().
+ ExpectStdoutMatchesSnapshot().
+ Run(t)
+ },
+ )
+}
diff --git a/internal/overrides/overrides.go b/internal/overrides/overrides.go
index 00bdc48..f2b6dc0 100644
--- a/internal/overrides/overrides.go
+++ b/internal/overrides/overrides.go
@@ -22,6 +22,7 @@ package overrides
import (
"fmt"
"regexp"
+ "strconv"
"strings"
"golang.org/x/exp/slices"
@@ -182,3 +183,18 @@ func ReleasePlatformSpecific(release int, info *distro.OSRelease) string {
return fmt.Sprintf("%d", release)
}
+
+func ParseReleasePlatformSpecific(s string, info *distro.OSRelease) (int, error) {
+ if info.ID == "altlinux" {
+ if strings.HasPrefix(s, "alt") {
+ return strconv.Atoi(s[3:])
+ }
+ }
+
+ if info.ID == "fedora" || slices.Contains(info.Like, "fedora") {
+ parts := strings.SplitN(s, ".", 2)
+ return strconv.Atoi(parts[0])
+ }
+
+ return strconv.Atoi(s)
+}
diff --git a/internal/overrides/overrides_test.go b/internal/overrides/overrides_test.go
index 42d985c..62a808d 100644
--- a/internal/overrides/overrides_test.go
+++ b/internal/overrides/overrides_test.go
@@ -233,5 +233,8 @@ func TestReleasePlatformSpecific(t *testing.T) {
},
} {
assert.Equal(t, tc.expected, overrides.ReleasePlatformSpecific(1, tc.info))
+ release, err := overrides.ParseReleasePlatformSpecific(tc.expected, tc.info)
+ assert.NoError(t, err)
+ assert.Equal(t, 1, release)
}
}
diff --git a/internal/translations/default.pot b/internal/translations/default.pot
index 687cd59..d5588e5 100644
--- a/internal/translations/default.pot
+++ b/internal/translations/default.pot
@@ -445,30 +445,34 @@ msgstr ""
msgid "You need to be root to perform this action"
msgstr ""
-#: list.go:43
+#: list.go:45
msgid "List ALR repo packages"
msgstr ""
-#: list.go:57
+#: list.go:59
msgid "Format output using a Go template"
msgstr ""
-#: list.go:89
+#: list.go:91
msgid "Error getting packages for upgrade"
msgstr ""
-#: list.go:92
+#: list.go:94
msgid "No packages for upgrade"
msgstr ""
-#: list.go:102 list.go:184
+#: list.go:104 list.go:201
msgid "Error parsing format template"
msgstr ""
-#: list.go:108 list.go:188
+#: list.go:110 list.go:205
msgid "Error executing template"
msgstr ""
+#: list.go:164
+msgid "Failed to parse release"
+msgstr ""
+
#: main.go:45
msgid "Print the current ALR version and exit"
msgstr ""
diff --git a/internal/translations/po/ru/default.po b/internal/translations/po/ru/default.po
index 6d9ba8f..8935dbf 100644
--- a/internal/translations/po/ru/default.po
+++ b/internal/translations/po/ru/default.po
@@ -5,15 +5,15 @@
msgid ""
msgstr ""
"Project-Id-Version: unnamed project\n"
-"PO-Revision-Date: 2025-06-29 21:05+0300\n"
+"PO-Revision-Date: 2025-07-09 20:38+0300\n"
"Last-Translator: Maxim Slipenko \n"
"Language-Team: Russian\n"
"Language: ru\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
-"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
+"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Gtranslator 48.0\n"
#: build.go:41
@@ -404,8 +404,8 @@ msgid ""
"This command is deprecated and would be removed in the future, use \"%s\" "
"instead!"
msgstr ""
-"Эта команда устарела и будет удалена в будущем, используйте вместо нее \"%s"
-"\"!"
+"Эта команда устарела и будет удалена в будущем, используйте вместо нее "
+"\"%s\"!"
#: internal/db/db.go:76
msgid "Database version mismatch; resetting"
@@ -461,30 +461,34 @@ msgstr "Вы должны быть членом %s чтобы выполнить
msgid "You need to be root to perform this action"
msgstr "Вы должны быть root чтобы выполнить это"
-#: list.go:43
+#: list.go:45
msgid "List ALR repo packages"
msgstr "Список пакетов репозитория ALR"
-#: list.go:57
+#: list.go:59
msgid "Format output using a Go template"
msgstr "Формат выходных данных с использованием шаблона Go"
-#: list.go:89
+#: list.go:91
msgid "Error getting packages for upgrade"
msgstr "Ошибка при получении пакетов для обновления"
-#: list.go:92
+#: list.go:94
msgid "No packages for upgrade"
msgstr "Нет пакетов к обновлению"
-#: list.go:102 list.go:184
+#: list.go:104 list.go:201
msgid "Error parsing format template"
msgstr "Ошибка при разборе шаблона"
-#: list.go:108 list.go:188
+#: list.go:110 list.go:205
msgid "Error executing template"
msgstr "Ошибка при выполнении шаблона"
+#: list.go:164
+msgid "Failed to parse release"
+msgstr "Не удалось разобрать релиз"
+
#: main.go:45
msgid "Print the current ALR version and exit"
msgstr "Показать текущую версию ALR и выйти"
diff --git a/list.go b/list.go
index 8d1ba69..b3a0dbb 100644
--- a/list.go
+++ b/list.go
@@ -24,6 +24,7 @@ import (
"log/slog"
"os"
"slices"
+ "strings"
"text/template"
"github.com/leonelquinteros/gotext"
@@ -33,6 +34,7 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
appbuilder "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils/app_builder"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/manager"
+ "gitea.plemya-x.ru/Plemya-x/ALR/internal/overrides"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/utils"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
)
@@ -126,7 +128,12 @@ func ListCmd() *cli.Command {
return cliutils.FormatCliExit(gotext.Get("Error getting packages"), err)
}
- installedAlrPackages := map[string]string{}
+ type verInfo struct {
+ Version string
+ Release int
+ }
+
+ installedAlrPackages := map[string]verInfo{}
if c.Bool("installed") {
mgr := manager.Detect()
if mgr == nil {
@@ -144,40 +151,50 @@ func ListCmd() *cli.Command {
if matches != nil {
packageName := matches[build.RegexpALRPackageName.SubexpIndex("package")]
repoName := matches[build.RegexpALRPackageName.SubexpIndex("repo")]
- installedAlrPackages[fmt.Sprintf("%s/%s", repoName, packageName)] = version
+
+ verInfo := verInfo{
+ Version: version,
+ Release: 0,
+ }
+
+ if i := strings.LastIndex(version, "-"); i != -1 {
+ verInfo.Version = version[:i]
+ verInfo.Release, err = overrides.ParseReleasePlatformSpecific(version[i+1:], info)
+ if err != nil {
+ slog.Error(gotext.Get("Failed to parse release"), "err", err)
+ return cli.Exit(err, 1)
+ }
+ }
+
+ installedAlrPackages[fmt.Sprintf("%s/%s", repoName, packageName)] = verInfo
}
}
}
for _, pkg := range result {
- if err != nil {
- return cli.Exit(err, 1)
- }
-
if slices.Contains(cfg.IgnorePkgUpdates(), pkg.Name) {
continue
}
type packageInfo struct {
Package *alrsh.Package
- Version string
}
pkgInfo := &packageInfo{}
pkgInfo.Package = &pkg
- pkgInfo.Version = pkg.Version
if c.Bool("installed") {
instVersion, ok := installedAlrPackages[fmt.Sprintf("%s/%s", pkg.Repository, pkg.Name)]
if !ok {
continue
} else {
- pkgInfo.Version = instVersion
+ pkg.Version = instVersion.Version
+ pkg.Release = instVersion.Release
}
}
format := c.String("format")
if format == "" {
- format = "{{.Package.Repository}}/{{.Package.Name}} {{.Version}}\n"
+ format = "{{.Package.Repository}}/{{.Package.Name}} {{.Package.Version}}-{{.Package.Release}}\n"
}
tmpl, err := template.New("format").Parse(format)
if err != nil {