forked from Plemya-x/ALR
		
	wip
This commit is contained in:
		| @@ -26,7 +26,6 @@ import ( | ||||
| 	"reflect" | ||||
|  | ||||
| 	"github.com/caarlos0/env" | ||||
| 	"github.com/leonelquinteros/gotext" | ||||
| 	"github.com/pelletier/go-toml/v2" | ||||
|  | ||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" | ||||
| @@ -84,7 +83,10 @@ func mergeStructs(dst, src interface{}) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| const systemConfigPath = "/etc/alr/alr.toml" | ||||
| const ( | ||||
| 	systemConfigPath = "/etc/alr/alr.toml" | ||||
| 	systemCachePath  = "/var/cache/alr" | ||||
| ) | ||||
|  | ||||
| func (c *ALRConfig) Load() error { | ||||
| 	systemConfig, err := readConfig( | ||||
| @@ -94,24 +96,10 @@ func (c *ALRConfig) Load() error { | ||||
| 		slog.Debug("Cannot read system config", "err", err) | ||||
| 	} | ||||
|  | ||||
| 	cfgDir, err := os.UserConfigDir() | ||||
| 	if err != nil { | ||||
| 		slog.Debug("Cannot read user config directory") | ||||
| 	} | ||||
| 	userConfigPath := filepath.Join(cfgDir, "alr", "alr.toml") | ||||
|  | ||||
| 	userConfig, err := readConfig( | ||||
| 		userConfigPath, | ||||
| 	) | ||||
| 	if err != nil { | ||||
| 		slog.Debug("Cannot read user config") | ||||
| 	} | ||||
|  | ||||
| 	config := &types.Config{} | ||||
|  | ||||
| 	mergeStructs(config, defaultConfig) | ||||
| 	mergeStructs(config, systemConfig) | ||||
| 	mergeStructs(config, userConfig) | ||||
| 	err = env.Parse(config) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| @@ -119,17 +107,13 @@ func (c *ALRConfig) Load() error { | ||||
|  | ||||
| 	c.cfg = config | ||||
|  | ||||
| 	cacheDir, err := os.UserCacheDir() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	c.paths = &Paths{} | ||||
| 	c.paths.UserConfigPath = userConfigPath | ||||
| 	c.paths.CacheDir = filepath.Join(cacheDir, "alr") | ||||
| 	c.paths.UserConfigPath = systemConfigPath | ||||
| 	c.paths.CacheDir = systemCachePath | ||||
| 	c.paths.RepoDir = filepath.Join(c.paths.CacheDir, "repo") | ||||
| 	c.paths.PkgsDir = filepath.Join(c.paths.CacheDir, "pkgs") | ||||
| 	c.paths.DBPath = filepath.Join(c.paths.CacheDir, "db") | ||||
| 	c.initPaths() | ||||
| 	// c.initPaths() | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
| @@ -170,26 +154,6 @@ func (c *ALRConfig) GetPaths() *Paths { | ||||
| 	return c.paths | ||||
| } | ||||
|  | ||||
| func (c *ALRConfig) initPaths() { | ||||
| 	err := os.MkdirAll(filepath.Dir(c.paths.UserConfigPath), 0o755) | ||||
| 	if err != nil { | ||||
| 		slog.Error(gotext.Get("Unable to create config directory"), "err", err) | ||||
| 		os.Exit(1) | ||||
| 	} | ||||
|  | ||||
| 	err = os.MkdirAll(c.paths.RepoDir, 0o755) | ||||
| 	if err != nil { | ||||
| 		slog.Error(gotext.Get("Unable to create repo cache directory"), "err", err) | ||||
| 		os.Exit(1) | ||||
| 	} | ||||
|  | ||||
| 	err = os.MkdirAll(c.paths.PkgsDir, 0o755) | ||||
| 	if err != nil { | ||||
| 		slog.Error(gotext.Get("Unable to create package cache directory"), "err", err) | ||||
| 		os.Exit(1) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (c *ALRConfig) SaveUserConfig() error { | ||||
| 	f, err := os.Create(c.paths.UserConfigPath) | ||||
| 	if err != nil { | ||||
|   | ||||
							
								
								
									
										136
									
								
								internal/logger/hclog.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								internal/logger/hclog.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,136 @@ | ||||
| // 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 logger | ||||
|  | ||||
| import ( | ||||
| 	"io" | ||||
| 	"log" | ||||
|  | ||||
| 	chLog "github.com/charmbracelet/log" | ||||
| 	"github.com/hashicorp/go-hclog" | ||||
| ) | ||||
|  | ||||
| type HCLoggerAdapter struct { | ||||
| 	logger *Logger | ||||
| } | ||||
|  | ||||
| func hclogLevelTochLog(level hclog.Level) chLog.Level { | ||||
| 	switch level { | ||||
| 	case hclog.Debug: | ||||
| 		return chLog.DebugLevel | ||||
| 	case hclog.Info: | ||||
| 		return chLog.InfoLevel | ||||
| 	case hclog.Warn: | ||||
| 		return chLog.WarnLevel | ||||
| 	case hclog.Error: | ||||
| 		return chLog.ErrorLevel | ||||
| 	} | ||||
| 	return chLog.FatalLevel | ||||
| } | ||||
|  | ||||
| func (a *HCLoggerAdapter) Log(level hclog.Level, msg string, args ...interface{}) { | ||||
| 	filteredArgs := make([]interface{}, 0, len(args)) | ||||
| 	for i := 0; i < len(args); i += 2 { | ||||
| 		if i+1 >= len(args) { | ||||
| 			filteredArgs = append(filteredArgs, args[i]) | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		key, ok := args[i].(string) | ||||
| 		if !ok || key != "timestamp" { | ||||
| 			filteredArgs = append(filteredArgs, args[i], args[i+1]) | ||||
| 		} | ||||
| 	} | ||||
| 	a.logger.l.Log(hclogLevelTochLog(level), msg, filteredArgs...) | ||||
| } | ||||
|  | ||||
| func (a *HCLoggerAdapter) Trace(msg string, args ...interface{}) { | ||||
| 	a.Log(hclog.Trace, msg, args...) | ||||
| } | ||||
|  | ||||
| func (a *HCLoggerAdapter) Debug(msg string, args ...interface{}) { | ||||
| 	a.Log(hclog.Debug, msg, args...) | ||||
| } | ||||
|  | ||||
| func (a *HCLoggerAdapter) Info(msg string, args ...interface{}) { | ||||
| 	a.Log(hclog.Info, msg, args...) | ||||
| } | ||||
|  | ||||
| func (a *HCLoggerAdapter) Warn(msg string, args ...interface{}) { | ||||
| 	a.Log(hclog.Warn, msg, args...) | ||||
| } | ||||
|  | ||||
| func (a *HCLoggerAdapter) Error(msg string, args ...interface{}) { | ||||
| 	a.Log(hclog.Error, msg, args...) | ||||
| } | ||||
|  | ||||
| func (a *HCLoggerAdapter) IsTrace() bool { | ||||
| 	return a.logger.l.GetLevel() <= chLog.DebugLevel | ||||
| } | ||||
|  | ||||
| func (a *HCLoggerAdapter) IsDebug() bool { | ||||
| 	return a.logger.l.GetLevel() <= chLog.DebugLevel | ||||
| } | ||||
|  | ||||
| func (a *HCLoggerAdapter) IsInfo() bool { | ||||
| 	return a.logger.l.GetLevel() <= chLog.InfoLevel | ||||
| } | ||||
|  | ||||
| func (a *HCLoggerAdapter) IsWarn() bool { | ||||
| 	return a.logger.l.GetLevel() <= chLog.WarnLevel | ||||
| } | ||||
|  | ||||
| func (a *HCLoggerAdapter) IsError() bool { | ||||
| 	return a.logger.l.GetLevel() <= chLog.ErrorLevel | ||||
| } | ||||
|  | ||||
| func (a *HCLoggerAdapter) ImpliedArgs() []interface{} { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (a *HCLoggerAdapter) With(args ...interface{}) hclog.Logger { | ||||
| 	return a | ||||
| } | ||||
|  | ||||
| func (a *HCLoggerAdapter) Name() string { | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| func (a *HCLoggerAdapter) Named(name string) hclog.Logger { | ||||
| 	return a | ||||
| } | ||||
|  | ||||
| func (a *HCLoggerAdapter) ResetNamed(name string) hclog.Logger { | ||||
| 	return a | ||||
| } | ||||
|  | ||||
| func (a *HCLoggerAdapter) SetLevel(level hclog.Level) { | ||||
| } | ||||
|  | ||||
| func (a *HCLoggerAdapter) StandardLogger(opts *hclog.StandardLoggerOptions) *log.Logger { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (a *HCLoggerAdapter) StandardWriter(opts *hclog.StandardLoggerOptions) io.Writer { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func GetHCLoggerAdapter() *HCLoggerAdapter { | ||||
| 	return &HCLoggerAdapter{ | ||||
| 		logger: logger, | ||||
| 	} | ||||
| } | ||||
| @@ -22,96 +22,90 @@ import ( | ||||
| 	"os" | ||||
|  | ||||
| 	"github.com/charmbracelet/lipgloss" | ||||
| 	"github.com/charmbracelet/log" | ||||
|  | ||||
| 	chLog "github.com/charmbracelet/log" | ||||
| 	"github.com/leonelquinteros/gotext" | ||||
| ) | ||||
|  | ||||
| type Logger struct { | ||||
| 	lOut slog.Handler | ||||
| 	lErr slog.Handler | ||||
| 	l *chLog.Logger | ||||
| } | ||||
|  | ||||
| func setupOutLogger() *log.Logger { | ||||
| 	styles := log.DefaultStyles() | ||||
| 	logger := log.New(os.Stdout) | ||||
| 	styles.Levels[log.InfoLevel] = lipgloss.NewStyle(). | ||||
| func setupLogger() *chLog.Logger { | ||||
| 	styles := chLog.DefaultStyles() | ||||
| 	logger := chLog.New(os.Stderr) | ||||
| 	styles.Levels[chLog.InfoLevel] = lipgloss.NewStyle(). | ||||
| 		SetString("-->"). | ||||
| 		Foreground(lipgloss.Color("35")) | ||||
| 	logger.SetStyles(styles) | ||||
| 	return logger | ||||
| } | ||||
|  | ||||
| func setupErrorLogger() *log.Logger { | ||||
| 	styles := log.DefaultStyles() | ||||
| 	styles.Levels[log.ErrorLevel] = lipgloss.NewStyle(). | ||||
| 	styles.Levels[chLog.ErrorLevel] = lipgloss.NewStyle(). | ||||
| 		SetString(gotext.Get("ERROR")). | ||||
| 		Padding(0, 1, 0, 1). | ||||
| 		Background(lipgloss.Color("204")). | ||||
| 		Foreground(lipgloss.Color("0")) | ||||
| 	logger := log.New(os.Stderr) | ||||
| 	logger.SetStyles(styles) | ||||
| 	return logger | ||||
| } | ||||
|  | ||||
| func New() *Logger { | ||||
| 	standardLogger := setupOutLogger() | ||||
| 	errLogger := setupErrorLogger() | ||||
| 	return &Logger{ | ||||
| 		lOut: standardLogger, | ||||
| 		lErr: errLogger, | ||||
| 		l: setupLogger(), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func slogLevelToLog(level slog.Level) log.Level { | ||||
| func slogLevelToLog(level slog.Level) chLog.Level { | ||||
| 	switch level { | ||||
| 	case slog.LevelDebug: | ||||
| 		return log.DebugLevel | ||||
| 		return chLog.DebugLevel | ||||
| 	case slog.LevelInfo: | ||||
| 		return log.InfoLevel | ||||
| 		return chLog.InfoLevel | ||||
| 	case slog.LevelWarn: | ||||
| 		return log.WarnLevel | ||||
| 		return chLog.WarnLevel | ||||
| 	case slog.LevelError: | ||||
| 		return log.ErrorLevel | ||||
| 		return chLog.ErrorLevel | ||||
| 	} | ||||
| 	return log.FatalLevel | ||||
| 	return chLog.FatalLevel | ||||
| } | ||||
|  | ||||
| func (l *Logger) SetLevel(level slog.Level) { | ||||
| 	l.lOut.(*log.Logger).SetLevel(slogLevelToLog(level)) | ||||
| 	l.lErr.(*log.Logger).SetLevel(slogLevelToLog(level)) | ||||
| 	l.l.SetLevel(slogLevelToLog(level)) | ||||
| } | ||||
|  | ||||
| func (l *Logger) Enabled(ctx context.Context, level slog.Level) bool { | ||||
| 	if level <= slog.LevelInfo { | ||||
| 		return l.lOut.Enabled(ctx, level) | ||||
| 	} | ||||
| 	return l.lErr.Enabled(ctx, level) | ||||
| 	return l.l.Enabled(ctx, level) | ||||
| } | ||||
|  | ||||
| func (l *Logger) Handle(ctx context.Context, rec slog.Record) error { | ||||
| 	if rec.Level <= slog.LevelInfo { | ||||
| 		return l.lOut.Handle(ctx, rec) | ||||
| 	} | ||||
| 	return l.lErr.Handle(ctx, rec) | ||||
| 	return l.l.Handle(ctx, rec) | ||||
| } | ||||
|  | ||||
| func (l *Logger) WithAttrs(attrs []slog.Attr) slog.Handler { | ||||
| 	sl := *l | ||||
| 	sl.lOut = l.lOut.WithAttrs(attrs) | ||||
| 	sl.lErr = l.lErr.WithAttrs(attrs) | ||||
| 	sl.l = l.l.WithAttrs(attrs).(*chLog.Logger) | ||||
| 	return &sl | ||||
| } | ||||
|  | ||||
| func (l *Logger) WithGroup(name string) slog.Handler { | ||||
| 	sl := *l | ||||
| 	sl.lOut = l.lOut.WithGroup(name) | ||||
| 	sl.lErr = l.lErr.WithGroup(name) | ||||
| 	sl.l = l.l.WithGroup(name).(*chLog.Logger) | ||||
| 	return &sl | ||||
| } | ||||
|  | ||||
| var logger *Logger | ||||
|  | ||||
| func SetupDefault() *Logger { | ||||
| 	l := New() | ||||
| 	logger := slog.New(l) | ||||
| 	slog.SetDefault(logger) | ||||
| 	return l | ||||
| 	logger = New() | ||||
| 	slogLogger := slog.New(logger) | ||||
| 	slog.SetDefault(slogLogger) | ||||
| 	return logger | ||||
| } | ||||
|  | ||||
| func SetupForGoPlugin() { | ||||
| 	logger.l.SetFormatter(chLog.JSONFormatter) | ||||
| 	chLog.TimestampKey = "@timestamp" | ||||
| 	chLog.MessageKey = "@message" | ||||
| 	chLog.LevelKey = "@level" | ||||
| } | ||||
|  | ||||
| func GetLogger() *Logger { | ||||
| 	return logger | ||||
| } | ||||
|   | ||||
| @@ -25,11 +25,11 @@ import ( | ||||
| 	"os" | ||||
| 	"os/exec" | ||||
| 	"runtime" | ||||
| 	"slices" | ||||
| 	"strings" | ||||
| 	"syscall" | ||||
| 	"time" | ||||
|  | ||||
| 	"gitea.plemya-x.ru/Plemya-x/fakeroot" | ||||
| 	"mvdan.cc/sh/v3/expand" | ||||
| 	"mvdan.cc/sh/v3/interp" | ||||
| ) | ||||
| @@ -54,7 +54,7 @@ func FakerootExecHandler(killTimeout time.Duration) interp.ExecHandlerFunc { | ||||
| 			Stderr: hc.Stderr, | ||||
| 		} | ||||
|  | ||||
| 		err = fakeroot.Apply(cmd) | ||||
| 		err = Apply(cmd) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| @@ -108,6 +108,52 @@ func FakerootExecHandler(killTimeout time.Duration) interp.ExecHandlerFunc { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func rootMap(m syscall.SysProcIDMap) bool { | ||||
| 	return m.ContainerID == 0 | ||||
| } | ||||
|  | ||||
| func Apply(cmd *exec.Cmd) error { | ||||
| 	uid := os.Getuid() | ||||
| 	gid := os.Getgid() | ||||
|  | ||||
| 	// If the user is already root, there's no need for fakeroot | ||||
| 	if uid == 0 { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	// Ensure SysProcAttr isn't nil | ||||
| 	if cmd.SysProcAttr == nil { | ||||
| 		cmd.SysProcAttr = &syscall.SysProcAttr{} | ||||
| 	} | ||||
|  | ||||
| 	// Create a new user namespace | ||||
| 	cmd.SysProcAttr.Cloneflags |= syscall.CLONE_NEWUSER | ||||
|  | ||||
| 	// If the command already contains a mapping for the root user, return an error | ||||
| 	if slices.ContainsFunc(cmd.SysProcAttr.UidMappings, rootMap) { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	// If the command already contains a mapping for the root group, return an error | ||||
| 	if slices.ContainsFunc(cmd.SysProcAttr.GidMappings, rootMap) { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	cmd.SysProcAttr.UidMappings = append(cmd.SysProcAttr.UidMappings, syscall.SysProcIDMap{ | ||||
| 		ContainerID: 0, | ||||
| 		HostID:      uid, | ||||
| 		Size:        1, | ||||
| 	}) | ||||
|  | ||||
| 	cmd.SysProcAttr.GidMappings = append(cmd.SysProcAttr.GidMappings, syscall.SysProcIDMap{ | ||||
| 		ContainerID: 0, | ||||
| 		HostID:      gid, | ||||
| 		Size:        1, | ||||
| 	}) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // execEnv was extracted from github.com/mvdan/sh/interp/vars.go | ||||
| func execEnv(env expand.Environ) []string { | ||||
| 	list := make([]string, 0, 64) | ||||
|   | ||||
| @@ -42,55 +42,63 @@ msgstr "" | ||||
| msgid "Package not found" | ||||
| msgstr "" | ||||
|  | ||||
| #: build.go:130 | ||||
| msgid "Error pulling repositories" | ||||
| msgstr "" | ||||
|  | ||||
| #: build.go:138 | ||||
| #: build.go:127 | ||||
| msgid "Unable to detect a supported package manager on the system" | ||||
| msgstr "" | ||||
|  | ||||
| #: build.go:144 | ||||
| #: build.go:133 | ||||
| msgid "Error parsing os release" | ||||
| msgstr "" | ||||
|  | ||||
| #: build.go:166 | ||||
| #: build.go:159 | ||||
| msgid "Error building package" | ||||
| msgstr "" | ||||
|  | ||||
| #: build.go:173 | ||||
| #: build.go:166 | ||||
| msgid "Error getting working directory" | ||||
| msgstr "" | ||||
|  | ||||
| #: build.go:182 | ||||
| #: build.go:175 | ||||
| msgid "Error moving the package" | ||||
| msgstr "" | ||||
|  | ||||
| #: fix.go:37 | ||||
| #: fix.go:39 | ||||
| msgid "Attempt to fix problems with ALR" | ||||
| msgstr "" | ||||
|  | ||||
| #: fix.go:49 | ||||
| #: fix.go:42 | ||||
| msgid "Can't drop privileges" | ||||
| msgstr "" | ||||
|  | ||||
| #: fix.go:56 | ||||
| msgid "Removing cache directory" | ||||
| msgstr "" | ||||
|  | ||||
| #: fix.go:53 | ||||
| msgid "Unable to remove cache directory" | ||||
| #: fix.go:60 | ||||
| msgid "Unable to open cache directory" | ||||
| msgstr "" | ||||
|  | ||||
| #: fix.go:57 | ||||
| #: fix.go:67 | ||||
| msgid "Unable to read cache directory contents" | ||||
| msgstr "" | ||||
|  | ||||
| #: fix.go:74 | ||||
| msgid "Unable to remove cache item" | ||||
| msgstr "" | ||||
|  | ||||
| #: fix.go:79 | ||||
| msgid "Rebuilding cache" | ||||
| msgstr "" | ||||
|  | ||||
| #: fix.go:61 | ||||
| #: fix.go:83 | ||||
| msgid "Unable to create new cache directory" | ||||
| msgstr "" | ||||
|  | ||||
| #: fix.go:81 | ||||
| #: fix.go:103 | ||||
| msgid "Error pulling repos" | ||||
| msgstr "" | ||||
|  | ||||
| #: fix.go:85 | ||||
| #: fix.go:107 | ||||
| msgid "Done" | ||||
| msgstr "" | ||||
|  | ||||
| @@ -162,19 +170,27 @@ msgstr "" | ||||
| msgid "Command install expected at least 1 argument, got %d" | ||||
| msgstr "" | ||||
|  | ||||
| #: install.go:163 | ||||
| #: install.go:84 | ||||
| msgid "Error dropping capabilities" | ||||
| msgstr "" | ||||
|  | ||||
| #: install.go:96 | ||||
| msgid "Error pulling repositories" | ||||
| msgstr "" | ||||
|  | ||||
| #: install.go:164 | ||||
| msgid "Remove an installed package" | ||||
| msgstr "" | ||||
|  | ||||
| #: install.go:188 | ||||
| #: install.go:189 | ||||
| msgid "Error listing installed packages" | ||||
| msgstr "" | ||||
|  | ||||
| #: install.go:226 | ||||
| #: install.go:227 | ||||
| msgid "Command remove expected at least 1 argument, got %d" | ||||
| msgstr "" | ||||
|  | ||||
| #: install.go:241 | ||||
| #: install.go:242 | ||||
| msgid "Error removing packages" | ||||
| msgstr "" | ||||
|  | ||||
| @@ -258,18 +274,6 @@ msgstr "" | ||||
| msgid "OPTIONS" | ||||
| msgstr "" | ||||
|  | ||||
| #: internal/config/config.go:176 | ||||
| msgid "Unable to create config directory" | ||||
| msgstr "" | ||||
|  | ||||
| #: internal/config/config.go:182 | ||||
| msgid "Unable to create repo cache directory" | ||||
| msgstr "" | ||||
|  | ||||
| #: internal/config/config.go:188 | ||||
| msgid "Unable to create package cache directory" | ||||
| msgstr "" | ||||
|  | ||||
| #: internal/db/db.go:133 | ||||
| msgid "Database version mismatch; resetting" | ||||
| msgstr "" | ||||
| @@ -303,10 +307,14 @@ msgstr "" | ||||
| msgid "%s %s downloading at %s/s\n" | ||||
| msgstr "" | ||||
|  | ||||
| #: internal/logger/log.go:47 | ||||
| #: internal/logger/log.go:41 | ||||
| msgid "ERROR" | ||||
| msgstr "" | ||||
|  | ||||
| #: internal/utils/cmd.go:65 | ||||
| msgid "You need to be root" | ||||
| msgstr "" | ||||
|  | ||||
| #: list.go:41 | ||||
| msgid "List ALR repo packages" | ||||
| msgstr "" | ||||
| @@ -315,94 +323,48 @@ msgstr "" | ||||
| msgid "Print the current ALR version and exit" | ||||
| msgstr "" | ||||
|  | ||||
| #: main.go:61 | ||||
| #: main.go:79 | ||||
| msgid "Arguments to be passed on to the package manager" | ||||
| msgstr "" | ||||
|  | ||||
| #: main.go:67 | ||||
| #: main.go:85 | ||||
| msgid "Enable interactive questions and prompts" | ||||
| msgstr "" | ||||
|  | ||||
| #: main.go:96 | ||||
| msgid "" | ||||
| "Running ALR as root is forbidden as it may cause catastrophic damage to your " | ||||
| "system" | ||||
| msgstr "" | ||||
|  | ||||
| #: main.go:154 | ||||
| #: main.go:183 | ||||
| msgid "Show help" | ||||
| msgstr "" | ||||
|  | ||||
| #: main.go:158 | ||||
| #: main.go:187 | ||||
| msgid "Error while running app" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:157 | ||||
| msgid "Failed to prompt user to view build script" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:161 | ||||
| #: pkg/build/build.go:392 | ||||
| msgid "Building package" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:209 | ||||
| #: pkg/build/build.go:421 | ||||
| msgid "The checksums array must be the same length as sources" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:238 | ||||
| #: pkg/build/build.go:448 | ||||
| msgid "Downloading sources" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:260 | ||||
| msgid "Building package metadata" | ||||
| #: pkg/build/build.go:507 | ||||
| msgid "Installing dependencies" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:282 | ||||
| msgid "Compressing package" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:441 | ||||
| #: pkg/build/checker.go:43 | ||||
| msgid "" | ||||
| "Your system's CPU architecture doesn't match this package. Do you want to " | ||||
| "build anyway?" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:455 | ||||
| #: pkg/build/checker.go:67 | ||||
| msgid "This package is already installed" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:479 | ||||
| msgid "Installing build dependencies" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:524 | ||||
| msgid "Installing dependencies" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:605 | ||||
| msgid "Would you like to remove the build dependencies?" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:668 | ||||
| msgid "Executing prepare()" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:678 | ||||
| msgid "Executing build()" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:708 pkg/build/build.go:728 | ||||
| msgid "Executing %s()" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:787 | ||||
| msgid "Error installing native packages" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:811 | ||||
| msgid "Error installing package" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/find_deps/alt_linux.go:35 | ||||
| msgid "Command not found on the system" | ||||
| msgstr "" | ||||
| @@ -423,6 +385,22 @@ msgstr "" | ||||
| msgid "AutoReq is not implemented for this package format, so it's skipped" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/script_executor.go:236 | ||||
| msgid "Building package metadata" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/script_executor.go:355 | ||||
| msgid "Executing prepare()" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/script_executor.go:364 | ||||
| msgid "Executing build()" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/script_executor.go:393 pkg/build/script_executor.go:413 | ||||
| msgid "Executing %s()" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/repos/pull.go:79 | ||||
| msgid "Pulling repository" | ||||
| msgstr "" | ||||
| @@ -441,86 +419,74 @@ msgid "" | ||||
| "updating ALR if something doesn't work." | ||||
| msgstr "" | ||||
|  | ||||
| #: repo.go:40 | ||||
| #: repo.go:41 | ||||
| msgid "Add a new repository" | ||||
| msgstr "" | ||||
|  | ||||
| #: repo.go:47 | ||||
| #: repo.go:48 | ||||
| msgid "Name of the new repo" | ||||
| msgstr "" | ||||
|  | ||||
| #: repo.go:53 | ||||
| #: repo.go:54 | ||||
| msgid "URL of the new repo" | ||||
| msgstr "" | ||||
|  | ||||
| #: repo.go:86 repo.go:156 | ||||
| #: repo.go:89 repo.go:166 | ||||
| msgid "Error saving config" | ||||
| msgstr "" | ||||
|  | ||||
| #: repo.go:111 | ||||
| #: repo.go:119 | ||||
| msgid "Remove an existing repository" | ||||
| msgstr "" | ||||
|  | ||||
| #: repo.go:118 | ||||
| #: repo.go:126 | ||||
| msgid "Name of the repo to be deleted" | ||||
| msgstr "" | ||||
|  | ||||
| #: repo.go:142 | ||||
| #: repo.go:152 | ||||
| msgid "Repo does not exist" | ||||
| msgstr "" | ||||
|  | ||||
| #: repo.go:150 | ||||
| #: repo.go:160 | ||||
| msgid "Error removing repo directory" | ||||
| msgstr "" | ||||
|  | ||||
| #: repo.go:167 | ||||
| #: repo.go:177 | ||||
| msgid "Error removing packages from database" | ||||
| msgstr "" | ||||
|  | ||||
| #: repo.go:179 | ||||
| #: repo.go:189 | ||||
| msgid "Pull all repositories that have changed" | ||||
| msgstr "" | ||||
|  | ||||
| #: search.go:36 | ||||
| #: search.go:37 | ||||
| msgid "Search packages" | ||||
| msgstr "" | ||||
|  | ||||
| #: search.go:42 | ||||
| #: search.go:43 | ||||
| msgid "Search by name" | ||||
| msgstr "" | ||||
|  | ||||
| #: search.go:47 | ||||
| #: search.go:48 | ||||
| msgid "Search by description" | ||||
| msgstr "" | ||||
|  | ||||
| #: search.go:52 | ||||
| #: search.go:53 | ||||
| msgid "Search by repository" | ||||
| msgstr "" | ||||
|  | ||||
| #: search.go:57 | ||||
| #: search.go:58 | ||||
| msgid "Search by provides" | ||||
| msgstr "" | ||||
|  | ||||
| #: search.go:62 | ||||
| #: search.go:63 | ||||
| msgid "Format output using a Go template" | ||||
| msgstr "" | ||||
|  | ||||
| #: search.go:88 search.go:105 | ||||
| #: search.go:94 search.go:111 | ||||
| msgid "Error parsing format template" | ||||
| msgstr "" | ||||
|  | ||||
| #: search.go:113 | ||||
| #: search.go:119 | ||||
| msgid "Error executing template" | ||||
| msgstr "" | ||||
|  | ||||
| #: upgrade.go:47 | ||||
| msgid "Upgrade all installed packages" | ||||
| msgstr "" | ||||
|  | ||||
| #: upgrade.go:96 | ||||
| msgid "Error checking for updates" | ||||
| msgstr "" | ||||
|  | ||||
| #: upgrade.go:118 | ||||
| msgid "There is nothing to do." | ||||
| msgstr "" | ||||
|   | ||||
| @@ -50,55 +50,66 @@ msgstr "Ошибка инициализации базы данных" | ||||
| msgid "Package not found" | ||||
| msgstr "Пакет не найден" | ||||
|  | ||||
| #: build.go:130 | ||||
| msgid "Error pulling repositories" | ||||
| msgstr "Ошибка при извлечении репозиториев" | ||||
|  | ||||
| #: build.go:138 | ||||
| #: build.go:127 | ||||
| msgid "Unable to detect a supported package manager on the system" | ||||
| msgstr "Не удалось обнаружить поддерживаемый менеджер пакетов в системе" | ||||
|  | ||||
| #: build.go:144 | ||||
| #: build.go:133 | ||||
| msgid "Error parsing os release" | ||||
| msgstr "Ошибка при разборе файла выпуска операционной системы" | ||||
|  | ||||
| #: build.go:166 | ||||
| #: build.go:159 | ||||
| msgid "Error building package" | ||||
| msgstr "Ошибка при сборке пакета" | ||||
|  | ||||
| #: build.go:173 | ||||
| #: build.go:166 | ||||
| msgid "Error getting working directory" | ||||
| msgstr "Ошибка при получении рабочего каталога" | ||||
|  | ||||
| #: build.go:182 | ||||
| #: build.go:175 | ||||
| msgid "Error moving the package" | ||||
| msgstr "Ошибка при перемещении пакета" | ||||
|  | ||||
| #: fix.go:37 | ||||
| #: fix.go:39 | ||||
| msgid "Attempt to fix problems with ALR" | ||||
| msgstr "Попытка устранить проблемы с ALR" | ||||
|  | ||||
| #: fix.go:49 | ||||
| #: fix.go:42 | ||||
| msgid "Can't drop privileges" | ||||
| msgstr "" | ||||
|  | ||||
| #: fix.go:56 | ||||
| msgid "Removing cache directory" | ||||
| msgstr "Удаление каталога кэша" | ||||
|  | ||||
| #: fix.go:53 | ||||
| msgid "Unable to remove cache directory" | ||||
| #: fix.go:60 | ||||
| #, fuzzy | ||||
| msgid "Unable to open cache directory" | ||||
| msgstr "Не удалось удалить каталог кэша" | ||||
|  | ||||
| #: fix.go:57 | ||||
| #: fix.go:67 | ||||
| #, fuzzy | ||||
| msgid "Unable to read cache directory contents" | ||||
| msgstr "Не удалось удалить каталог кэша" | ||||
|  | ||||
| #: fix.go:74 | ||||
| #, fuzzy | ||||
| msgid "Unable to remove cache item" | ||||
| msgstr "Не удалось удалить каталог кэша" | ||||
|  | ||||
| #: fix.go:79 | ||||
| msgid "Rebuilding cache" | ||||
| msgstr "Восстановление кэша" | ||||
|  | ||||
| #: fix.go:61 | ||||
| #: fix.go:83 | ||||
| msgid "Unable to create new cache directory" | ||||
| msgstr "Не удалось создать новый каталог кэша" | ||||
|  | ||||
| #: fix.go:81 | ||||
| #: fix.go:103 | ||||
| msgid "Error pulling repos" | ||||
| msgstr "Ошибка при извлечении репозиториев" | ||||
|  | ||||
| #: fix.go:85 | ||||
| #: fix.go:107 | ||||
| msgid "Done" | ||||
| msgstr "Сделано" | ||||
|  | ||||
| @@ -170,19 +181,28 @@ msgstr "Установить новый пакет" | ||||
| msgid "Command install expected at least 1 argument, got %d" | ||||
| msgstr "Для команды install ожидался хотя бы 1 аргумент, получено %d" | ||||
|  | ||||
| #: install.go:163 | ||||
| #: install.go:84 | ||||
| #, fuzzy | ||||
| msgid "Error dropping capabilities" | ||||
| msgstr "Ошибка при открытии базы данных" | ||||
|  | ||||
| #: install.go:96 | ||||
| msgid "Error pulling repositories" | ||||
| msgstr "Ошибка при извлечении репозиториев" | ||||
|  | ||||
| #: install.go:164 | ||||
| msgid "Remove an installed package" | ||||
| msgstr "Удалить установленный пакет" | ||||
|  | ||||
| #: install.go:188 | ||||
| #: install.go:189 | ||||
| msgid "Error listing installed packages" | ||||
| msgstr "Ошибка при составлении списка установленных пакетов" | ||||
|  | ||||
| #: install.go:226 | ||||
| #: install.go:227 | ||||
| msgid "Command remove expected at least 1 argument, got %d" | ||||
| msgstr "Для команды remove ожидался хотя бы 1 аргумент, получено %d" | ||||
|  | ||||
| #: install.go:241 | ||||
| #: install.go:242 | ||||
| msgid "Error removing packages" | ||||
| msgstr "Ошибка при удалении пакетов" | ||||
|  | ||||
| @@ -266,19 +286,6 @@ msgstr "КАТЕГОРИЯ" | ||||
| msgid "OPTIONS" | ||||
| msgstr "ПАРАМЕТРЫ" | ||||
|  | ||||
| #: internal/config/config.go:176 | ||||
| #, fuzzy | ||||
| msgid "Unable to create config directory" | ||||
| msgstr "Не удалось создать каталог конфигурации ALR" | ||||
|  | ||||
| #: internal/config/config.go:182 | ||||
| msgid "Unable to create repo cache directory" | ||||
| msgstr "Не удалось создать каталог кэша репозитория" | ||||
|  | ||||
| #: internal/config/config.go:188 | ||||
| msgid "Unable to create package cache directory" | ||||
| msgstr "Не удалось создать каталог кэша пакетов" | ||||
|  | ||||
| #: internal/db/db.go:133 | ||||
| msgid "Database version mismatch; resetting" | ||||
| msgstr "Несоответствие версий базы данных; сброс настроек" | ||||
| @@ -313,10 +320,14 @@ msgstr "%s: выполнено!\n" | ||||
| msgid "%s %s downloading at %s/s\n" | ||||
| msgstr "%s %s загружается — %s/с\n" | ||||
|  | ||||
| #: internal/logger/log.go:47 | ||||
| #: internal/logger/log.go:41 | ||||
| msgid "ERROR" | ||||
| msgstr "ОШИБКА" | ||||
|  | ||||
| #: internal/utils/cmd.go:65 | ||||
| msgid "You need to be root" | ||||
| msgstr "" | ||||
|  | ||||
| #: list.go:41 | ||||
| msgid "List ALR repo packages" | ||||
| msgstr "Список пакетов репозитория ALR" | ||||
| @@ -325,55 +336,39 @@ msgstr "Список пакетов репозитория ALR" | ||||
| msgid "Print the current ALR version and exit" | ||||
| msgstr "Показать текущую версию ALR и выйти" | ||||
|  | ||||
| #: main.go:61 | ||||
| #: main.go:79 | ||||
| msgid "Arguments to be passed on to the package manager" | ||||
| msgstr "Аргументы, которые будут переданы менеджеру пакетов" | ||||
|  | ||||
| #: main.go:67 | ||||
| #: main.go:85 | ||||
| msgid "Enable interactive questions and prompts" | ||||
| msgstr "Включение интерактивных вопросов и запросов" | ||||
|  | ||||
| #: main.go:96 | ||||
| msgid "" | ||||
| "Running ALR as root is forbidden as it may cause catastrophic damage to your " | ||||
| "system" | ||||
| msgstr "" | ||||
| "Запуск ALR от имени root запрещён, так как это может привести к " | ||||
| "катастрофическому повреждению вашей системы" | ||||
|  | ||||
| #: main.go:154 | ||||
| #: main.go:183 | ||||
| msgid "Show help" | ||||
| msgstr "Показать справку" | ||||
|  | ||||
| #: main.go:158 | ||||
| #: main.go:187 | ||||
| msgid "Error while running app" | ||||
| msgstr "Ошибка при запуске приложения" | ||||
|  | ||||
| #: pkg/build/build.go:157 | ||||
| msgid "Failed to prompt user to view build script" | ||||
| msgstr "Не удалось предложить пользователю просмотреть скрипт сборки" | ||||
|  | ||||
| #: pkg/build/build.go:161 | ||||
| #: pkg/build/build.go:392 | ||||
| msgid "Building package" | ||||
| msgstr "Сборка пакета" | ||||
|  | ||||
| #: pkg/build/build.go:209 | ||||
| #: pkg/build/build.go:421 | ||||
| msgid "The checksums array must be the same length as sources" | ||||
| msgstr "Массив контрольных сумм должен быть той же длины, что и источники" | ||||
|  | ||||
| #: pkg/build/build.go:238 | ||||
| #: pkg/build/build.go:448 | ||||
| msgid "Downloading sources" | ||||
| msgstr "Скачивание источников" | ||||
|  | ||||
| #: pkg/build/build.go:260 | ||||
| msgid "Building package metadata" | ||||
| msgstr "Сборка метаданных пакета" | ||||
| #: pkg/build/build.go:507 | ||||
| msgid "Installing dependencies" | ||||
| msgstr "Установка зависимостей" | ||||
|  | ||||
| #: pkg/build/build.go:282 | ||||
| msgid "Compressing package" | ||||
| msgstr "Сжатие пакета" | ||||
|  | ||||
| #: pkg/build/build.go:441 | ||||
| #: pkg/build/checker.go:43 | ||||
| msgid "" | ||||
| "Your system's CPU architecture doesn't match this package. Do you want to " | ||||
| "build anyway?" | ||||
| @@ -381,42 +376,10 @@ msgstr "" | ||||
| "Архитектура процессора вашей системы не соответствует этому пакету. Вы все " | ||||
| "равно хотите выполнить сборку?" | ||||
|  | ||||
| #: pkg/build/build.go:455 | ||||
| #: pkg/build/checker.go:67 | ||||
| msgid "This package is already installed" | ||||
| msgstr "Этот пакет уже установлен" | ||||
|  | ||||
| #: pkg/build/build.go:479 | ||||
| msgid "Installing build dependencies" | ||||
| msgstr "Установка зависимостей сборки" | ||||
|  | ||||
| #: pkg/build/build.go:524 | ||||
| msgid "Installing dependencies" | ||||
| msgstr "Установка зависимостей" | ||||
|  | ||||
| #: pkg/build/build.go:605 | ||||
| msgid "Would you like to remove the build dependencies?" | ||||
| msgstr "Хотели бы вы удалить зависимости сборки?" | ||||
|  | ||||
| #: pkg/build/build.go:668 | ||||
| msgid "Executing prepare()" | ||||
| msgstr "Исполнение prepare()" | ||||
|  | ||||
| #: pkg/build/build.go:678 | ||||
| msgid "Executing build()" | ||||
| msgstr "Исполнение build()" | ||||
|  | ||||
| #: pkg/build/build.go:708 pkg/build/build.go:728 | ||||
| msgid "Executing %s()" | ||||
| msgstr "Исполнение %s()" | ||||
|  | ||||
| #: pkg/build/build.go:787 | ||||
| msgid "Error installing native packages" | ||||
| msgstr "Ошибка при установке нативных пакетов" | ||||
|  | ||||
| #: pkg/build/build.go:811 | ||||
| msgid "Error installing package" | ||||
| msgstr "Ошибка при установке пакета" | ||||
|  | ||||
| #: pkg/build/find_deps/alt_linux.go:35 | ||||
| msgid "Command not found on the system" | ||||
| msgstr "Команда не найдена в системе" | ||||
| @@ -439,6 +402,22 @@ msgid "AutoReq is not implemented for this package format, so it's skipped" | ||||
| msgstr "" | ||||
| "AutoReq не реализовано для этого формата пакета, поэтому будет пропущено" | ||||
|  | ||||
| #: pkg/build/script_executor.go:236 | ||||
| msgid "Building package metadata" | ||||
| msgstr "Сборка метаданных пакета" | ||||
|  | ||||
| #: pkg/build/script_executor.go:355 | ||||
| msgid "Executing prepare()" | ||||
| msgstr "Исполнение prepare()" | ||||
|  | ||||
| #: pkg/build/script_executor.go:364 | ||||
| msgid "Executing build()" | ||||
| msgstr "Исполнение build()" | ||||
|  | ||||
| #: pkg/build/script_executor.go:393 pkg/build/script_executor.go:413 | ||||
| msgid "Executing %s()" | ||||
| msgstr "Исполнение %s()" | ||||
|  | ||||
| #: pkg/repos/pull.go:79 | ||||
| msgid "Pulling repository" | ||||
| msgstr "Скачивание репозитория" | ||||
| @@ -459,90 +438,122 @@ msgstr "" | ||||
| "Минимальная версия ALR для ALR-репозитория выше текущей версии. Попробуйте " | ||||
| "обновить ALR, если что-то не работает." | ||||
|  | ||||
| #: repo.go:40 | ||||
| #: repo.go:41 | ||||
| msgid "Add a new repository" | ||||
| msgstr "Добавить новый репозиторий" | ||||
|  | ||||
| #: repo.go:47 | ||||
| #: repo.go:48 | ||||
| msgid "Name of the new repo" | ||||
| msgstr "Название нового репозитория" | ||||
|  | ||||
| #: repo.go:53 | ||||
| #: repo.go:54 | ||||
| msgid "URL of the new repo" | ||||
| msgstr "URL-адрес нового репозитория" | ||||
|  | ||||
| #: repo.go:86 repo.go:156 | ||||
| #: repo.go:89 repo.go:166 | ||||
| #, fuzzy | ||||
| msgid "Error saving config" | ||||
| msgstr "Ошибка при кодировании конфигурации" | ||||
|  | ||||
| #: repo.go:111 | ||||
| #: repo.go:119 | ||||
| msgid "Remove an existing repository" | ||||
| msgstr "Удалить существующий репозиторий" | ||||
|  | ||||
| #: repo.go:118 | ||||
| #: repo.go:126 | ||||
| msgid "Name of the repo to be deleted" | ||||
| msgstr "Название репозитория  удалён" | ||||
|  | ||||
| #: repo.go:142 | ||||
| #: repo.go:152 | ||||
| msgid "Repo does not exist" | ||||
| msgstr "Репозитория не существует" | ||||
|  | ||||
| #: repo.go:150 | ||||
| #: repo.go:160 | ||||
| msgid "Error removing repo directory" | ||||
| msgstr "Ошибка при удалении каталога репозитория" | ||||
|  | ||||
| #: repo.go:167 | ||||
| #: repo.go:177 | ||||
| msgid "Error removing packages from database" | ||||
| msgstr "Ошибка при удалении пакетов из базы данных" | ||||
|  | ||||
| #: repo.go:179 | ||||
| #: repo.go:189 | ||||
| msgid "Pull all repositories that have changed" | ||||
| msgstr "Скачать все изменённые репозитории" | ||||
|  | ||||
| #: search.go:36 | ||||
| #: search.go:37 | ||||
| msgid "Search packages" | ||||
| msgstr "Поиск пакетов" | ||||
|  | ||||
| #: search.go:42 | ||||
| #: search.go:43 | ||||
| msgid "Search by name" | ||||
| msgstr "Искать по имени" | ||||
|  | ||||
| #: search.go:47 | ||||
| #: search.go:48 | ||||
| msgid "Search by description" | ||||
| msgstr "Искать по описанию" | ||||
|  | ||||
| #: search.go:52 | ||||
| #: search.go:53 | ||||
| msgid "Search by repository" | ||||
| msgstr "Искать по репозиторию" | ||||
|  | ||||
| #: search.go:57 | ||||
| #: search.go:58 | ||||
| msgid "Search by provides" | ||||
| msgstr "Иcкать по provides" | ||||
|  | ||||
| #: search.go:62 | ||||
| #: search.go:63 | ||||
| msgid "Format output using a Go template" | ||||
| msgstr "Формат выходных данных с использованием шаблона Go" | ||||
|  | ||||
| #: search.go:88 search.go:105 | ||||
| #: search.go:94 search.go:111 | ||||
| msgid "Error parsing format template" | ||||
| msgstr "Ошибка при разборе шаблона" | ||||
|  | ||||
| #: search.go:113 | ||||
| #: search.go:119 | ||||
| msgid "Error executing template" | ||||
| msgstr "Ошибка при выполнении шаблона" | ||||
|  | ||||
| #: upgrade.go:47 | ||||
| msgid "Upgrade all installed packages" | ||||
| msgstr "Обновить все установленные пакеты" | ||||
| #, fuzzy | ||||
| #~ msgid "Unable to create config directory" | ||||
| #~ msgstr "Не удалось создать каталог конфигурации ALR" | ||||
|  | ||||
| #: upgrade.go:96 | ||||
| msgid "Error checking for updates" | ||||
| msgstr "Ошибка при проверке обновлений" | ||||
| #~ msgid "Unable to create repo cache directory" | ||||
| #~ msgstr "Не удалось создать каталог кэша репозитория" | ||||
|  | ||||
| #: upgrade.go:118 | ||||
| msgid "There is nothing to do." | ||||
| msgstr "Здесь нечего делать." | ||||
| #~ msgid "Unable to create package cache directory" | ||||
| #~ msgstr "Не удалось создать каталог кэша пакетов" | ||||
|  | ||||
| #~ msgid "" | ||||
| #~ "Running ALR as root is forbidden as it may cause catastrophic damage to " | ||||
| #~ "your system" | ||||
| #~ msgstr "" | ||||
| #~ "Запуск ALR от имени root запрещён, так как это может привести к " | ||||
| #~ "катастрофическому повреждению вашей системы" | ||||
|  | ||||
| #~ msgid "Failed to prompt user to view build script" | ||||
| #~ msgstr "Не удалось предложить пользователю просмотреть скрипт сборки" | ||||
|  | ||||
| #~ msgid "Compressing package" | ||||
| #~ msgstr "Сжатие пакета" | ||||
|  | ||||
| #~ msgid "Installing build dependencies" | ||||
| #~ msgstr "Установка зависимостей сборки" | ||||
|  | ||||
| #~ msgid "Would you like to remove the build dependencies?" | ||||
| #~ msgstr "Хотели бы вы удалить зависимости сборки?" | ||||
|  | ||||
| #~ msgid "Error installing native packages" | ||||
| #~ msgstr "Ошибка при установке нативных пакетов" | ||||
|  | ||||
| #~ msgid "Error installing package" | ||||
| #~ msgstr "Ошибка при установке пакета" | ||||
|  | ||||
| #~ msgid "Upgrade all installed packages" | ||||
| #~ msgstr "Обновить все установленные пакеты" | ||||
|  | ||||
| #~ msgid "Error checking for updates" | ||||
| #~ msgstr "Ошибка при проверке обновлений" | ||||
|  | ||||
| #~ msgid "There is nothing to do." | ||||
| #~ msgstr "Здесь нечего делать." | ||||
|  | ||||
| #~ msgid "Error opening config file, using defaults" | ||||
| #~ msgstr "" | ||||
| @@ -572,9 +583,6 @@ msgstr "Здесь нечего делать." | ||||
| #~ msgid "Error parsing system language" | ||||
| #~ msgstr "Ошибка при парсинге языка системы" | ||||
|  | ||||
| #~ msgid "Error opening database" | ||||
| #~ msgstr "Ошибка при открытии базы данных" | ||||
|  | ||||
| #~ msgid "Executing version()" | ||||
| #~ msgstr "Исполнение версия()" | ||||
|  | ||||
|   | ||||
| @@ -19,13 +19,11 @@ | ||||
|  | ||||
| package types | ||||
|  | ||||
| import "gitea.plemya-x.ru/Plemya-x/ALR/pkg/manager" | ||||
|  | ||||
| type BuildOpts struct { | ||||
| 	Script      string | ||||
| 	Repository  string | ||||
| 	Packages    []string | ||||
| 	Manager     manager.Manager | ||||
| 	// Script      string | ||||
| 	// Repository  string | ||||
| 	// Packages    []string | ||||
| 	// Manager     manager.Manager | ||||
| 	Clean       bool | ||||
| 	Interactive bool | ||||
| } | ||||
|   | ||||
							
								
								
									
										68
									
								
								internal/utils/cmd.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								internal/utils/cmd.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| // 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 utils | ||||
|  | ||||
| import ( | ||||
| 	"log/slog" | ||||
| 	"os" | ||||
| 	"os/user" | ||||
| 	"strconv" | ||||
| 	"syscall" | ||||
|  | ||||
| 	"github.com/leonelquinteros/gotext" | ||||
| ) | ||||
|  | ||||
| func GetUidGidAlrUser() (int, int, error) { | ||||
| 	u, err := user.Lookup("alr") | ||||
| 	if err != nil { | ||||
| 		return 0, 0, err | ||||
| 	} | ||||
|  | ||||
| 	uid, err := strconv.Atoi(u.Uid) | ||||
| 	if err != nil { | ||||
| 		return 0, 0, err | ||||
| 	} | ||||
| 	gid, err := strconv.Atoi(u.Gid) | ||||
| 	if err != nil { | ||||
| 		return 0, 0, err | ||||
| 	} | ||||
|  | ||||
| 	return uid, gid, nil | ||||
| } | ||||
|  | ||||
| func DropCapsToAlrUser() error { | ||||
| 	uid, gid, err := GetUidGidAlrUser() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	err = syscall.Setgid(gid) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	err = syscall.Setuid(uid) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func ExitIfNotRoot() { | ||||
| 	if os.Getuid() != 0 { | ||||
| 		slog.Error(gotext.Get("You need to be root")) | ||||
| 		os.Exit(1) | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user