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"> <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="15" fill="#010101" fill-opacity=".3">ru translate</text>
<text x="37" y="14">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="15" fill="#010101" fill-opacity=".3">97.00%</text>
<text x="100" y="14">100.00%</text> <text x="100" y="14">97.00%</text>
</g> </g>
</svg> </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", "issue-32-interactive",
COMMON_SYSTEMS, COMMON_SYSTEMS,
func(t *testing.T, r e2e.Runnable) { 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", "sudo", "alr", "--interactive=false", "remove", "ca-certificates",
))) ))
assert.NoError(t, err)
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",
)))
}, },
) )
} }

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

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

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

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

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

@ -28,12 +28,12 @@ func NewInstaller(mgr manager.Manager) *Installer {
type Installer struct{ mgr manager.Manager } type Installer struct{ mgr manager.Manager }
func (i *Installer) InstallLocal(paths []string, opts *manager.Opts) error { func (i *Installer) InstallLocal(paths []string) error {
return i.mgr.InstallLocal(opts, paths...) return i.mgr.InstallLocal(nil, paths...)
} }
func (i *Installer) Install(pkgs []string, opts *manager.Opts) error { func (i *Installer) Install(pkgs []string) error {
return i.mgr.Install(opts, pkgs...) return i.mgr.Install(nil, pkgs...)
} }
func (i *Installer) RemoveAlreadyInstalled(pkgs []string) ([]string, error) { 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" "github.com/hashicorp/go-plugin"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/logger" "gitea.plemya-x.ru/Plemya-x/ALR/internal/logger"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/manager"
) )
type InstallerPlugin struct { type InstallerPlugin struct {
@ -43,31 +42,21 @@ type InstallerRPCServer struct {
Impl InstallerExecutor Impl InstallerExecutor
} }
type InstallArgs struct { func (r *InstallerRPC) InstallLocal(paths []string) error {
PackagesOrPaths []string return r.client.Call("Plugin.InstallLocal", paths, nil)
Opts *manager.Opts
} }
func (r *InstallerRPC) InstallLocal(paths []string, opts *manager.Opts) error { func (s *InstallerRPCServer) InstallLocal(paths []string, reply *struct{}) error {
return r.client.Call("Plugin.InstallLocal", &InstallArgs{ return s.Impl.InstallLocal(paths)
PackagesOrPaths: paths,
Opts: opts,
}, nil)
} }
func (s *InstallerRPCServer) InstallLocal(args *InstallArgs, reply *struct{}) error { func (r *InstallerRPC) Install(pkgs []string) error {
return s.Impl.InstallLocal(args.PackagesOrPaths, args.Opts) return r.client.Call("Plugin.Install", pkgs, nil)
} }
func (r *InstallerRPC) Install(pkgs []string, opts *manager.Opts) error { func (s *InstallerRPCServer) Install(pkgs []string, reply *struct{}) error {
return r.client.Call("Plugin.Install", &InstallArgs{ slog.Debug("install", "pkgs", pkgs)
PackagesOrPaths: pkgs, return s.Impl.Install(pkgs)
Opts: opts,
}, nil)
}
func (s *InstallerRPCServer) Install(args *InstallArgs, reply *struct{}) error {
return s.Impl.Install(args.PackagesOrPaths, args.Opts)
} }
func (r *InstallerRPC) RemoveAlreadyInstalled(paths []string) ([]string, error) { func (r *InstallerRPC) RemoveAlreadyInstalled(paths []string) ([]string, error) {
@ -101,7 +90,28 @@ func GetSafeInstaller() (InstallerExecutor, func(), error) {
return nil, nil, err return nil, nil, err
} }
cmd := exec.Command(executable, "_internal-installer") 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()) 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") 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{ client := plugin.NewClient(&plugin.ClientConfig{
HandshakeConfig: HandshakeConfig, HandshakeConfig: HandshakeConfig,

@ -76,7 +76,7 @@ func AddRepoCmd() *cli.Command {
reposSlice := cfg.Repos() reposSlice := cfg.Repos()
for _, repo := range reposSlice { for _, repo := range reposSlice {
if repo.URL == repoURL || repo.Name == name { 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{ reposSlice = append(reposSlice, types.Repo{