diff --git a/assets/coverage-badge.svg b/assets/coverage-badge.svg
index cfa4439..5a9d2fc 100644
--- a/assets/coverage-badge.svg
+++ b/assets/coverage-badge.svg
@@ -11,7 +11,7 @@
coverage
coverage
- 15.7%
- 15.7%
+ 15.8%
+ 15.8%
diff --git a/helper.go b/helper.go
index 074e702..19eaf39 100644
--- a/helper.go
+++ b/helper.go
@@ -71,19 +71,19 @@ func HelperCmd() *cli.Command {
helper, ok := helpers.Helpers[c.Args().First()]
if !ok {
slog.Error(gotext.Get("No such helper command"), "name", c.Args().First())
- os.Exit(1)
+ return cli.Exit(gotext.Get("No such helper command"), 1)
}
wd, err := os.Getwd()
if err != nil {
- slog.Error(gotext.Get("Error getting working directory"), "err", err)
- os.Exit(1)
+ slog.Error(gotext.Get("Error getting working directory"))
+ return cli.Exit(err, 1)
}
info, err := distro.ParseOSRelease(ctx)
if err != nil {
- slog.Error(gotext.Get("Error getting working directory"), "err", err)
- os.Exit(1)
+ slog.Error(gotext.Get("Error parsing os-release file"))
+ return cli.Exit(err, 1)
}
hc := interp.HandlerContext{
diff --git a/info.go b/info.go
index 02f462c..a2555be 100644
--- a/info.go
+++ b/info.go
@@ -31,7 +31,6 @@ 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/config"
database "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/overrides"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/utils"
@@ -49,31 +48,26 @@ func InfoCmd() *cli.Command {
Usage: gotext.Get("Show all information, not just for the current distro"),
},
},
- BashComplete: func(c *cli.Context) {
+ BashComplete: cliutils.BashCompleteWithError(func(c *cli.Context) error {
if err := utils.ExitIfCantDropCapsToAlrUser(); err != nil {
- slog.Error("Can't drop caps")
- os.Exit(1)
+ return err
}
ctx := c.Context
- cfg := config.New()
- err := cfg.Load()
+ deps, err := appbuilder.
+ New(ctx).
+ WithConfig().
+ WithDB().
+ Build()
if err != nil {
- slog.Error(gotext.Get("Error loading config"), "err", err)
- os.Exit(1)
+ return err
}
+ defer deps.Defer()
- db := database.New(cfg)
- err = db.Init(ctx)
+ result, err := deps.DB.GetPkgs(c.Context, "true")
if err != nil {
- slog.Error(gotext.Get("Error initialization database"), "err", err)
- os.Exit(1)
- }
-
- result, err := db.GetPkgs(c.Context, "true")
- if err != nil {
- slog.Error(gotext.Get("Error getting packages"), "err", err)
- os.Exit(1)
+ slog.Error(gotext.Get("Error getting packages"))
+ return cli.Exit(err, 1)
}
defer result.Close()
@@ -81,13 +75,14 @@ func InfoCmd() *cli.Command {
var pkg database.Package
err = result.StructScan(&pkg)
if err != nil {
- slog.Error(gotext.Get("Error iterating over packages"), "err", err)
- os.Exit(1)
+ slog.Error(gotext.Get("Error iterating over packages"))
+ return cli.Exit(err, 1)
}
fmt.Println(pkg.Name)
}
- },
+ return nil
+ }),
Action: func(c *cli.Context) error {
if err := utils.ExitIfCantDropCapsToAlrUser(); err != nil {
return err
diff --git a/internal/cliutils/app_builder/builder.go b/internal/cliutils/app_builder/builder.go
index 6ced528..0aa9bf4 100644
--- a/internal/cliutils/app_builder/builder.go
+++ b/internal/cliutils/app_builder/builder.go
@@ -92,6 +92,16 @@ func (b *AppBuilder) WithDB() *AppBuilder {
}
func (b *AppBuilder) WithRepos() *AppBuilder {
+ b.withRepos(false)
+ return b
+}
+
+func (b *AppBuilder) WithReposForcePull() *AppBuilder {
+ b.withRepos(true)
+ return b
+}
+
+func (b *AppBuilder) withRepos(forcePull bool) *AppBuilder {
if b.err != nil {
return b
}
@@ -105,7 +115,7 @@ func (b *AppBuilder) WithRepos() *AppBuilder {
rs := repos.New(cfg, db)
- if cfg.AutoPull() {
+ if forcePull || cfg.AutoPull() {
if err := rs.Pull(b.ctx, cfg.Repos()); err != nil {
slog.Error(gotext.Get("Error pulling repositories"), "err", err)
b.err = cli.Exit("", 1)
diff --git a/internal/cliutils/utils.go b/internal/cliutils/utils.go
new file mode 100644
index 0000000..fca0c8d
--- /dev/null
+++ b/internal/cliutils/utils.go
@@ -0,0 +1,48 @@
+// ALR - Any Linux Repository
+// Copyright (C) 2025 Евгений Храмов
+//
+// 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 .
+
+package cliutils
+
+import (
+ "fmt"
+ "log/slog"
+
+ "github.com/urfave/cli/v2"
+)
+
+type BashCompleteWithErrorFunc func(c *cli.Context) error
+
+func BashCompleteWithError(f BashCompleteWithErrorFunc) cli.BashCompleteFunc {
+ return func(c *cli.Context) { HandleExitCoder(f(c)) }
+}
+
+func HandleExitCoder(err error) {
+ if err == nil {
+ return
+ }
+
+ if exitErr, ok := err.(cli.ExitCoder); ok {
+ if err.Error() != "" {
+ if _, ok := exitErr.(cli.ErrorFormatter); ok {
+ slog.Error(fmt.Sprintf("%+v\n", err))
+ } else {
+ slog.Error(err.Error())
+ }
+ }
+ cli.OsExiter(exitErr.ExitCode())
+ return
+ }
+}
diff --git a/internal/translations/default.pot b/internal/translations/default.pot
index 2a9d038..ee8b45c 100644
--- a/internal/translations/default.pot
+++ b/internal/translations/default.pot
@@ -122,47 +122,47 @@ msgstr ""
msgid "The directory that the install commands will install to"
msgstr ""
-#: helper.go:73
+#: helper.go:73 helper.go:74
msgid "No such helper command"
msgstr ""
-#: info.go:44
-msgid "Print information about a package"
-msgstr ""
-
-#: info.go:49
-msgid "Show all information, not just for the current distro"
-msgstr ""
-
-#: info.go:75
-msgid "Error getting packages"
-msgstr ""
-
-#: info.go:84
-msgid "Error iterating over packages"
-msgstr ""
-
-#: info.go:98
-msgid "Command info expected at least 1 argument, got %d"
-msgstr ""
-
-#: info.go:118
-msgid "Error finding packages"
-msgstr ""
-
-#: info.go:134
-msgid "Can't detect system language"
-msgstr ""
-
-#: info.go:144
+#: helper.go:85
msgid "Error parsing os-release file"
msgstr ""
-#: info.go:153
+#: info.go:43
+msgid "Print information about a package"
+msgstr ""
+
+#: info.go:48
+msgid "Show all information, not just for the current distro"
+msgstr ""
+
+#: info.go:69
+msgid "Error getting packages"
+msgstr ""
+
+#: info.go:78
+msgid "Error iterating over packages"
+msgstr ""
+
+#: info.go:93
+msgid "Command info expected at least 1 argument, got %d"
+msgstr ""
+
+#: info.go:113
+msgid "Error finding packages"
+msgstr ""
+
+#: info.go:129
+msgid "Can't detect system language"
+msgstr ""
+
+#: info.go:148
msgid "Error resolving overrides"
msgstr ""
-#: info.go:162 info.go:168
+#: info.go:157 info.go:163
msgid "Error encoding script variables"
msgstr ""
@@ -315,7 +315,7 @@ msgstr ""
msgid "You need to be root to perform this action"
msgstr ""
-#: list.go:41
+#: list.go:40
msgid "List ALR repo packages"
msgstr ""
@@ -323,19 +323,19 @@ msgstr ""
msgid "Print the current ALR version and exit"
msgstr ""
-#: main.go:79
+#: main.go:61
msgid "Arguments to be passed on to the package manager"
msgstr ""
-#: main.go:85
+#: main.go:67
msgid "Enable interactive questions and prompts"
msgstr ""
-#: main.go:185
+#: main.go:148
msgid "Show help"
msgstr ""
-#: main.go:189
+#: main.go:152
msgid "Error while running app"
msgstr ""
@@ -419,51 +419,51 @@ msgid ""
"updating ALR if something doesn't work."
msgstr ""
-#: repo.go:41
+#: repo.go:42
msgid "Add a new repository"
msgstr ""
-#: repo.go:48
+#: repo.go:49
msgid "Name of the new repo"
msgstr ""
-#: repo.go:54
+#: repo.go:55
msgid "URL of the new repo"
msgstr ""
-#: repo.go:92 repo.go:172
+#: repo.go:93 repo.go:173
msgid "Error saving config"
msgstr ""
-#: repo.go:97 repo.go:199
+#: repo.go:98
msgid "Can't drop privileges"
msgstr ""
-#: repo.go:104 repo.go:110 repo.go:219
+#: repo.go:105 repo.go:111
msgid "Error pulling repos"
msgstr ""
-#: repo.go:122
+#: repo.go:123
msgid "Remove an existing repository"
msgstr ""
-#: repo.go:129
+#: repo.go:130
msgid "Name of the repo to be deleted"
msgstr ""
-#: repo.go:158
+#: repo.go:159
msgid "Repo does not exist"
msgstr ""
-#: repo.go:166
+#: repo.go:167
msgid "Error removing repo directory"
msgstr ""
-#: repo.go:183
+#: repo.go:184
msgid "Error removing packages from database"
msgstr ""
-#: repo.go:195
+#: repo.go:196
msgid "Pull all repositories that have changed"
msgstr ""
diff --git a/internal/translations/po/ru/default.po b/internal/translations/po/ru/default.po
index 285a637..e7deda5 100644
--- a/internal/translations/po/ru/default.po
+++ b/internal/translations/po/ru/default.po
@@ -136,48 +136,48 @@ msgstr "Запустить вспомогательную команду ALR"
msgid "The directory that the install commands will install to"
msgstr "Каталог, в который будут устанавливать команды установки"
-#: helper.go:73
+#: helper.go:73 helper.go:74
msgid "No such helper command"
msgstr "Такой вспомогательной команды нет"
-#: info.go:44
+#: helper.go:85
+msgid "Error parsing os-release file"
+msgstr "Ошибка при разборе файла выпуска операционной системы"
+
+#: info.go:43
msgid "Print information about a package"
msgstr "Отобразить информацию о пакете"
-#: info.go:49
+#: info.go:48
msgid "Show all information, not just for the current distro"
msgstr "Показывать всю информацию, не только для текущего дистрибутива"
-#: info.go:75
+#: info.go:69
msgid "Error getting packages"
msgstr "Ошибка при получении пакетов"
-#: info.go:84
+#: info.go:78
msgid "Error iterating over packages"
msgstr "Ошибка при переборе пакетов"
-#: info.go:98
+#: info.go:93
msgid "Command info expected at least 1 argument, got %d"
msgstr "Для команды info ожидался хотя бы 1 аргумент, получено %d"
-#: info.go:118
+#: info.go:113
msgid "Error finding packages"
msgstr "Ошибка при поиске пакетов"
-#: info.go:134
+#: info.go:129
#, fuzzy
msgid "Can't detect system language"
msgstr "Ошибка при парсинге языка системы"
-#: info.go:144
-msgid "Error parsing os-release file"
-msgstr "Ошибка при разборе файла выпуска операционной системы"
-
-#: info.go:153
+#: info.go:148
msgid "Error resolving overrides"
msgstr "Ошибка устранения переорпеделений"
-#: info.go:162 info.go:168
+#: info.go:157 info.go:163
msgid "Error encoding script variables"
msgstr "Ошибка кодирования переменных скрита"
@@ -331,7 +331,7 @@ msgstr "ОШИБКА"
msgid "You need to be root to perform this action"
msgstr ""
-#: list.go:41
+#: list.go:40
msgid "List ALR repo packages"
msgstr "Список пакетов репозитория ALR"
@@ -339,19 +339,19 @@ msgstr "Список пакетов репозитория ALR"
msgid "Print the current ALR version and exit"
msgstr "Показать текущую версию ALR и выйти"
-#: main.go:79
+#: main.go:61
msgid "Arguments to be passed on to the package manager"
msgstr "Аргументы, которые будут переданы менеджеру пакетов"
-#: main.go:85
+#: main.go:67
msgid "Enable interactive questions and prompts"
msgstr "Включение интерактивных вопросов и запросов"
-#: main.go:185
+#: main.go:148
msgid "Show help"
msgstr "Показать справку"
-#: main.go:189
+#: main.go:152
msgid "Error while running app"
msgstr "Ошибка при запуске приложения"
@@ -441,52 +441,52 @@ msgstr ""
"Минимальная версия ALR для ALR-репозитория выше текущей версии. Попробуйте "
"обновить ALR, если что-то не работает."
-#: repo.go:41
+#: repo.go:42
msgid "Add a new repository"
msgstr "Добавить новый репозиторий"
-#: repo.go:48
+#: repo.go:49
msgid "Name of the new repo"
msgstr "Название нового репозитория"
-#: repo.go:54
+#: repo.go:55
msgid "URL of the new repo"
msgstr "URL-адрес нового репозитория"
-#: repo.go:92 repo.go:172
+#: repo.go:93 repo.go:173
#, fuzzy
msgid "Error saving config"
msgstr "Ошибка при кодировании конфигурации"
-#: repo.go:97 repo.go:199
+#: repo.go:98
msgid "Can't drop privileges"
msgstr ""
-#: repo.go:104 repo.go:110 repo.go:219
+#: repo.go:105 repo.go:111
msgid "Error pulling repos"
msgstr "Ошибка при извлечении репозиториев"
-#: repo.go:122
+#: repo.go:123
msgid "Remove an existing repository"
msgstr "Удалить существующий репозиторий"
-#: repo.go:129
+#: repo.go:130
msgid "Name of the repo to be deleted"
msgstr "Название репозитория удалён"
-#: repo.go:158
+#: repo.go:159
msgid "Repo does not exist"
msgstr "Репозитория не существует"
-#: repo.go:166
+#: repo.go:167
msgid "Error removing repo directory"
msgstr "Ошибка при удалении каталога репозитория"
-#: repo.go:183
+#: repo.go:184
msgid "Error removing packages from database"
msgstr "Ошибка при удалении пакетов из базы данных"
-#: repo.go:195
+#: repo.go:196
msgid "Pull all repositories that have changed"
msgstr "Скачать все изменённые репозитории"
diff --git a/list.go b/list.go
index 413951a..c92e87b 100644
--- a/list.go
+++ b/list.go
@@ -22,7 +22,6 @@ package main
import (
"fmt"
"log/slog"
- "os"
"github.com/leonelquinteros/gotext"
"github.com/urfave/cli/v2"
@@ -77,8 +76,8 @@ func ListCmd() *cli.Command {
result, err := db.GetPkgs(ctx, where, args...)
if err != nil {
- slog.Error(gotext.Get("Error getting packages"), "err", err)
- os.Exit(1)
+ slog.Error(gotext.Get("Error getting packages"))
+ return cli.Exit(err, 1)
}
defer result.Close()
@@ -86,14 +85,13 @@ func ListCmd() *cli.Command {
if c.Bool("installed") {
mgr := manager.Detect()
if mgr == nil {
- slog.Error(gotext.Get("Unable to detect a supported package manager on the system"))
- os.Exit(1)
+ return cli.Exit(gotext.Get("Unable to detect a supported package manager on the system"), 1)
}
installed, err := mgr.ListInstalled(&manager.Opts{AsRoot: false})
if err != nil {
slog.Error(gotext.Get("Error listing installed packages"), "err", err)
- os.Exit(1)
+ return cli.Exit(err, 1)
}
for pkgName, version := range installed {
@@ -110,7 +108,7 @@ func ListCmd() *cli.Command {
var pkg database.Package
err := result.StructScan(&pkg)
if err != nil {
- return err
+ return cli.Exit(err, 1)
}
if slices.Contains(cfg.IgnorePkgUpdates(), pkg.Name) {
@@ -130,11 +128,6 @@ func ListCmd() *cli.Command {
fmt.Printf("%s/%s %s\n", pkg.Repository, pkg.Name, version)
}
- if err != nil {
- slog.Error(gotext.Get("Error iterating over packages"), "err", err)
- os.Exit(1)
- }
-
return nil
},
}
diff --git a/main.go b/main.go
index acffacb..3a28be3 100644
--- a/main.go
+++ b/main.go
@@ -21,10 +21,10 @@ package main
import (
"context"
- "fmt"
"log/slog"
"os"
"os/signal"
+ "strings"
"syscall"
"github.com/leonelquinteros/gotext"
@@ -50,24 +50,6 @@ func VersionCmd() *cli.Command {
}
}
-func HandleExitCoder(err error) {
- if err == nil {
- return
- }
-
- if exitErr, ok := err.(cli.ExitCoder); ok {
- if err.Error() != "" {
- if _, ok := exitErr.(cli.ErrorFormatter); ok {
- slog.Error(fmt.Sprintf("%+v\n", err))
- } else {
- slog.Error(err.Error())
- }
- }
- cli.OsExiter(exitErr.ExitCode())
- return
- }
-}
-
func GetApp() *cli.App {
return &cli.App{
Name: "alr",
@@ -100,41 +82,22 @@ func GetApp() *cli.App {
HelperCmd(),
VersionCmd(),
SearchCmd(),
- // TEST
+ // Internal commands
InternalBuildCmd(),
InternalInstallCmd(),
InternalMountCmd(),
InternalUnmountCmd(),
- // InternalBuild2Cmd(),
},
Before: func(c *cli.Context) error {
- /*
- cfg := config.New()
- err := cfg.Load()
- if err != nil {
- slog.Error(gotext.Get("Error loading config"), "err", err)
- os.Exit(1)
- }
-
- /*
- cmd := c.Args().First()
- if cmd != "helper" && !cfg.AllowRunAsRoot() && os.Geteuid() == 0 {
- slog.Error(gotext.Get("Running ALR as root is forbidden as it may cause catastrophic damage to your system"))
- os.Exit(1)
- }
-
-
- if trimmed := strings.TrimSpace(c.String("pm-args")); trimmed != "" {
- args := strings.Split(trimmed, " ")
- manager.Args = append(manager.Args, args...)
- }
-
- return nil
- */
+ if trimmed := strings.TrimSpace(c.String("pm-args")); trimmed != "" {
+ args := strings.Split(trimmed, " ")
+ manager.Args = append(manager.Args, args...)
+ }
return nil
},
EnableBashCompletion: true,
- ExitErrHandler: func(c *cli.Context, err error) {
+ ExitErrHandler: func(cCtx *cli.Context, err error) {
+ cliutils.HandleExitCoder(err)
},
}
}
diff --git a/repo.go b/repo.go
index 7a599c2..2c5428c 100644
--- a/repo.go
+++ b/repo.go
@@ -28,6 +28,7 @@ import (
"github.com/urfave/cli/v2"
"golang.org/x/exp/slices"
+ appbuilder "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils/app_builder"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
database "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types"
@@ -195,30 +196,22 @@ func RefreshCmd() *cli.Command {
Usage: gotext.Get("Pull all repositories that have changed"),
Aliases: []string{"ref"},
Action: func(c *cli.Context) error {
- if utils.DropCapsToAlrUser() != nil {
- slog.Error(gotext.Get("Can't drop privileges"))
- os.Exit(1)
+ if err := utils.ExitIfCantDropCapsToAlrUser(); err != nil {
+ return err
}
ctx := c.Context
- cfg := config.New()
- err := cfg.Load()
- if err != nil {
- slog.Error(gotext.Get("Error loading config"), "err", err)
- os.Exit(1)
- }
- db := database.New(cfg)
- err = db.Init(ctx)
+ deps, err := appbuilder.
+ New(ctx).
+ WithConfig().
+ WithDB().
+ WithReposForcePull().
+ Build()
if err != nil {
- os.Exit(1)
- }
- rs := repos.New(cfg, db)
- err = rs.Pull(ctx, cfg.Repos())
- if err != nil {
- slog.Error(gotext.Get("Error pulling repos"), "err", err)
- os.Exit(1)
+ return err
}
+ defer deps.Defer()
return nil
},
}