Compare commits

..

No commits in common. "7bbceb76c9defab2c3f55591ec3630efc287464d" and "3483cf57f8b863da057605c593a9f46da99cfac5" have entirely different histories.

12 changed files with 114 additions and 137 deletions

@ -12,7 +12,7 @@
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="37" y="15" fill="#010101" fill-opacity=".3">ru translate</text>
<text x="37" y="14">ru translate</text>
<text x="100" y="15" fill="#010101" fill-opacity=".3">100.00%</text>
<text x="100" y="14">100.00%</text>
<text x="100" y="15" fill="#010101" fill-opacity=".3">97.00%</text>
<text x="100" y="14">97.00%</text>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 942 B

After

Width:  |  Height:  |  Size: 940 B

@ -31,21 +31,10 @@ func TestE2EIssue32Interactive(t *testing.T) {
"issue-32-interactive",
COMMON_SYSTEMS,
func(t *testing.T, r e2e.Runnable) {
assert.NoError(t, r.Exec(e2e.NewCommand(
err := r.Exec(e2e.NewCommand(
"sudo", "alr", "--interactive=false", "remove", "ca-certificates",
)))
assert.NoError(t, r.Exec(e2e.NewCommand(
"sudo", "alr", "--interactive=false", "remove", "openssl",
)))
assert.NoError(t, r.Exec(e2e.NewCommand(
"alr", "fix",
)))
assert.NoError(t, r.Exec(e2e.NewCommand(
"sudo", "alr", "--interactive=false", "install", "ca-certificates",
)))
))
assert.NoError(t, err)
},
)
}

@ -46,9 +46,6 @@ func HandleExitCoder(err error) {
cli.OsExiter(exitErr.ExitCode())
return
}
slog.Error(err.Error())
cli.OsExiter(1)
}
func FormatCliExit(msg string, err error) cli.ExitCoder {

@ -312,7 +312,7 @@ msgid "ERROR"
msgstr ""
#: internal/utils/cmd.go:95
msgid "Error on dropping capabilities"
msgid "Error dropping capabilities"
msgstr ""
#: internal/utils/cmd.go:123
@ -347,19 +347,19 @@ msgstr ""
msgid "Error while running app"
msgstr ""
#: pkg/build/build.go:395
#: pkg/build/build.go:394
msgid "Building package"
msgstr ""
#: pkg/build/build.go:424
#: pkg/build/build.go:423
msgid "The checksums array must be the same length as sources"
msgstr ""
#: pkg/build/build.go:455
#: pkg/build/build.go:454
msgid "Downloading sources"
msgstr ""
#: pkg/build/build.go:549
#: pkg/build/build.go:543
msgid "Installing dependencies"
msgstr ""
@ -440,7 +440,7 @@ msgid "URL of the new repo"
msgstr ""
#: repo.go:79
msgid "Repo \"%s\" already exists"
msgid "Repo %s already exists"
msgstr ""
#: repo.go:90 repo.go:167

@ -5,16 +5,16 @@
msgid ""
msgstr ""
"Project-Id-Version: unnamed project\n"
"PO-Revision-Date: 2025-04-18 07:38+0300\n"
"PO-Revision-Date: 2025-03-09 17:31+0300\n"
"Last-Translator: Maxim Slipenko <maks1ms@alt-gnome.ru>\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"
"X-Generator: Gtranslator 48.0\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 47.1\n"
#: build.go:42
msgid "Build a local package"
@ -43,15 +43,16 @@ msgstr "Ошибка при получении рабочего каталога
#: build.go:118
msgid "Cannot get absolute script path"
msgstr "Невозможно получить абсолютный путь к скрипту"
msgstr ""
#: build.go:148
msgid "Package not found"
msgstr "Пакет не найден"
#: build.go:161
#, fuzzy
msgid "Nothing to build"
msgstr "Нечего собирать"
msgstr "Исполнение build()"
#: build.go:218
msgid "Error building package"
@ -70,20 +71,24 @@ msgid "Attempt to fix problems with ALR"
msgstr "Попытка устранить проблемы с ALR"
#: fix.go:59
#, fuzzy
msgid "Clearing cache directory"
msgstr "Очистка каталога кэша"
msgstr "Удаление каталога кэша"
#: fix.go:64
#, fuzzy
msgid "Unable to open cache directory"
msgstr "Невозможно открыть каталог кэша"
msgstr "Не удалось удалить каталог кэша"
#: fix.go:70
#, fuzzy
msgid "Unable to read cache directory contents"
msgstr "Невозможно прочитать содержимое каталога кэша"
msgstr "Не удалось удалить каталог кэша"
#: fix.go:76
#, fuzzy
msgid "Unable to remove cache item (%s)"
msgstr "Невозможно удалить элемент кэша (%s)"
msgstr "Не удалось удалить каталог кэша"
#: fix.go:80
msgid "Rebuilding cache"
@ -146,8 +151,9 @@ msgid "Error finding packages"
msgstr "Ошибка при поиске пакетов"
#: info.go:124
#, fuzzy
msgid "Can't detect system language"
msgstr "Ошибка при определении языка системы"
msgstr "Ошибка при парсинге языка системы"
#: info.go:141
msgid "Error resolving overrides"
@ -186,8 +192,9 @@ msgid "Error removing packages"
msgstr "Ошибка при удалении пакетов"
#: internal/cliutils/app_builder/builder.go:75
#, fuzzy
msgid "Error loading config"
msgstr "Ошибка при загрузке"
msgstr "Ошибка при кодировании конфигурации"
#: internal/cliutils/app_builder/builder.go:96
msgid "Error initialization database"
@ -320,16 +327,17 @@ msgid "ERROR"
msgstr "ОШИБКА"
#: internal/utils/cmd.go:95
msgid "Error on dropping capabilities"
msgstr "Ошибка при понижении привилегий"
#, fuzzy
msgid "Error dropping capabilities"
msgstr "Ошибка при открытии базы данных"
#: internal/utils/cmd.go:123
msgid "You need to be root to perform this action"
msgstr "Вы должны быть root чтобы выполнить это"
msgstr ""
#: internal/utils/cmd.go:165
msgid "You need to be a %s member to perform this action"
msgstr "Вы должны быть членом %s чтобы выполнить это"
msgstr ""
#: list.go:41
msgid "List ALR repo packages"
@ -355,19 +363,19 @@ msgstr "Показать справку"
msgid "Error while running app"
msgstr "Ошибка при запуске приложения"
#: pkg/build/build.go:395
#: pkg/build/build.go:394
msgid "Building package"
msgstr "Сборка пакета"
#: pkg/build/build.go:424
#: pkg/build/build.go:423
msgid "The checksums array must be the same length as sources"
msgstr "Массив контрольных сумм должен быть той же длины, что и источники"
#: pkg/build/build.go:455
#: pkg/build/build.go:454
msgid "Downloading sources"
msgstr "Скачивание источников"
#: pkg/build/build.go:549
#: pkg/build/build.go:543
msgid "Installing dependencies"
msgstr "Установка зависимостей"
@ -411,15 +419,15 @@ msgstr "Сборка метаданных пакета"
#: pkg/build/script_executor.go:356
msgid "Executing prepare()"
msgstr "Выполнение prepare()"
msgstr "Исполнение prepare()"
#: pkg/build/script_executor.go:365
msgid "Executing build()"
msgstr "Выполнение build()"
msgstr "Исполнение build()"
#: pkg/build/script_executor.go:394 pkg/build/script_executor.go:414
msgid "Executing %s()"
msgstr "Выполнение %s()"
msgstr "Исполнение %s()"
#: pkg/repos/pull.go:79
msgid "Pulling repository"
@ -454,12 +462,14 @@ msgid "URL of the new repo"
msgstr "URL-адрес нового репозитория"
#: repo.go:79
msgid "Repo \"%s\" already exists"
msgstr "Репозиторий \"%s\" уже существует"
#, fuzzy
msgid "Repo %s already exists"
msgstr "Репозитория не существует"
#: repo.go:90 repo.go:167
#, fuzzy
msgid "Error saving config"
msgstr "Ошибка при сохранении конфигурации"
msgstr "Ошибка при кодировании конфигурации"
#: repo.go:116
msgid "Remove an existing repository"
@ -470,8 +480,9 @@ msgid "Name of the repo to be deleted"
msgstr "Название репозитория удалён"
#: repo.go:156
#, fuzzy
msgid "Repo \"%s\" does not exist"
msgstr "Репозитория \"%s\" не существует"
msgstr "Репозитория не существует"
#: repo.go:163
msgid "Error removing repo directory"
@ -510,8 +521,9 @@ msgid "Format output using a Go template"
msgstr "Формат выходных данных с использованием шаблона Go"
#: search.go:96
#, fuzzy
msgid "Error while executing search"
msgstr "Ошибка при выполнении поиска"
msgstr "Ошибка при запуске приложения"
#: search.go:104
msgid "Error parsing format template"

@ -92,14 +92,14 @@ func ExitIfCantDropGidToAlr() cli.ExitCoder {
func ExitIfCantDropCapsToAlrUser() cli.ExitCoder {
err := DropCapsToAlrUser()
if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error on dropping capabilities"), err)
return cliutils.FormatCliExit(gotext.Get("Error dropping capabilities"), err)
}
return nil
}
func ExitIfCantSetNoNewPrivs() cli.ExitCoder {
if err := NoNewPrivs(); err != nil {
return cliutils.FormatCliExit("error on NoNewPrivs", err)
return cliutils.FormatCliExit("error no new privs", err)
}
return nil

@ -35,7 +35,6 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/manager"
)
type BuildInput struct {
@ -234,8 +233,8 @@ type CheckerExecutor interface {
}
type InstallerExecutor interface {
InstallLocal(paths []string, opts *manager.Opts) error
Install(pkgs []string, opts *manager.Opts) error
InstallLocal(paths []string) error
Install(pkgs []string) error
RemoveAlreadyInstalled(pkgs []string) ([]string, error)
}
@ -522,12 +521,7 @@ func (b *Builder) InstallALRPackages(
return err
}
err = b.installerExecutor.InstallLocal(
res.PackagePaths,
&manager.Opts{
NoConfirm: !input.BuildOpts().Interactive,
},
)
err = b.installerExecutor.InstallLocal(res.PackagePaths)
if err != nil {
return err
}
@ -687,18 +681,14 @@ func (i *Builder) InstallPkgs(
}
if len(builtPaths) > 0 {
err = i.installerExecutor.InstallLocal(builtPaths, &manager.Opts{
NoConfirm: !input.BuildOpts().Interactive,
})
err = i.installerExecutor.InstallLocal(builtPaths)
if err != nil {
return err
}
}
if len(repoDeps) > 0 {
err = i.installerExecutor.Install(repoDeps, &manager.Opts{
NoConfirm: !input.BuildOpts().Interactive,
})
err = i.installerExecutor.Install(repoDeps)
if err != nil {
return err
}

@ -28,12 +28,12 @@ func NewInstaller(mgr manager.Manager) *Installer {
type Installer struct{ mgr manager.Manager }
func (i *Installer) InstallLocal(paths []string, opts *manager.Opts) error {
return i.mgr.InstallLocal(opts, paths...)
func (i *Installer) InstallLocal(paths []string) error {
return i.mgr.InstallLocal(nil, paths...)
}
func (i *Installer) Install(pkgs []string, opts *manager.Opts) error {
return i.mgr.Install(opts, pkgs...)
func (i *Installer) Install(pkgs []string) error {
return i.mgr.Install(nil, pkgs...)
}
func (i *Installer) RemoveAlreadyInstalled(pkgs []string) ([]string, error) {

@ -1,40 +0,0 @@
// 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 <http://www.gnu.org/licenses/>.
package build
import (
"os"
"os/exec"
"strings"
)
func setCommonCmdEnv(cmd *exec.Cmd) {
cmd.Env = []string{
"HOME=/var/cache/alr",
"LOGNAME=alr",
"USER=alr",
"PATH=/usr/bin:/bin:/usr/local/bin",
}
for _, env := range os.Environ() {
if strings.HasPrefix(env, "LANG=") ||
strings.HasPrefix(env, "LANGUAGE=") ||
strings.HasPrefix(env, "LC_") ||
strings.HasPrefix(env, "ALR_LOG_LEVEL=") {
cmd.Env = append(cmd.Env, env)
}
}
}

@ -28,7 +28,6 @@ import (
"github.com/hashicorp/go-plugin"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/logger"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/manager"
)
type InstallerPlugin struct {
@ -43,31 +42,21 @@ type InstallerRPCServer struct {
Impl InstallerExecutor
}
type InstallArgs struct {
PackagesOrPaths []string
Opts *manager.Opts
func (r *InstallerRPC) InstallLocal(paths []string) error {
return r.client.Call("Plugin.InstallLocal", paths, nil)
}
func (r *InstallerRPC) InstallLocal(paths []string, opts *manager.Opts) error {
return r.client.Call("Plugin.InstallLocal", &InstallArgs{
PackagesOrPaths: paths,
Opts: opts,
}, nil)
func (s *InstallerRPCServer) InstallLocal(paths []string, reply *struct{}) error {
return s.Impl.InstallLocal(paths)
}
func (s *InstallerRPCServer) InstallLocal(args *InstallArgs, reply *struct{}) error {
return s.Impl.InstallLocal(args.PackagesOrPaths, args.Opts)
func (r *InstallerRPC) Install(pkgs []string) error {
return r.client.Call("Plugin.Install", pkgs, nil)
}
func (r *InstallerRPC) Install(pkgs []string, opts *manager.Opts) error {
return r.client.Call("Plugin.Install", &InstallArgs{
PackagesOrPaths: pkgs,
Opts: opts,
}, nil)
}
func (s *InstallerRPCServer) Install(args *InstallArgs, reply *struct{}) error {
return s.Impl.Install(args.PackagesOrPaths, args.Opts)
func (s *InstallerRPCServer) Install(pkgs []string, reply *struct{}) error {
slog.Debug("install", "pkgs", pkgs)
return s.Impl.Install(pkgs)
}
func (r *InstallerRPC) RemoveAlreadyInstalled(paths []string) ([]string, error) {
@ -101,7 +90,28 @@ func GetSafeInstaller() (InstallerExecutor, func(), error) {
return nil, nil, err
}
cmd := exec.Command(executable, "_internal-installer")
setCommonCmdEnv(cmd)
cmd.Env = []string{
"HOME=/var/cache/alr",
"LOGNAME=alr",
"USER=alr",
"PATH=/usr/bin:/bin:/usr/local/bin",
"ALR_LOG_LEVEL=DEBUG",
}
/*
uid, gid, err := utils.GetUidGidAlrUser()
if err != nil {
return nil, nil, err
}
cmd.SysProcAttr = &syscall.SysProcAttr{
Credential: &syscall.Credential{
Uid: uint32(uid),
Gid: uint32(gid),
},
}
*/
slog.Debug("safe installer setup", "uid", syscall.Getuid(), "gid", syscall.Getgid())

@ -226,7 +226,26 @@ func GetSafeScriptExecutor() (ScriptExecutor, func(), error) {
}
cmd := exec.Command(executable, "_internal-safe-script-executor")
setCommonCmdEnv(cmd)
cmd.Env = []string{
"HOME=/var/cache/alr",
"LOGNAME=alr",
"USER=alr",
"PATH=/usr/bin:/bin:/usr/local/bin",
"ALR_LOG_LEVEL=DEBUG",
}
/*
uid, gid, err := utils.GetUidGidAlrUser()
if err != nil {
return nil, nil, err
}
cmd.SysProcAttr = &syscall.SysProcAttr{
Credential: &syscall.Credential{
Uid: uint32(uid),
Gid: uint32(gid),
},
}
*/
client := plugin.NewClient(&plugin.ClientConfig{
HandshakeConfig: HandshakeConfig,

@ -76,7 +76,7 @@ func AddRepoCmd() *cli.Command {
reposSlice := cfg.Repos()
for _, repo := range reposSlice {
if repo.URL == repoURL || repo.Name == name {
return cliutils.FormatCliExit(gotext.Get("Repo \"%s\" already exists", repo.Name), nil)
return cliutils.FormatCliExit(gotext.Get("Repo %s already exists", repo.Name), nil)
}
}
reposSlice = append(reposSlice, types.Repo{