8 Commits

Author SHA1 Message Date
7060e4f551 chore: refactor Makefile with build and install improvements
All checks were successful
Pre-commit / pre-commit (pull_request) Successful in 5m29s
Update alr-git / changelog (push) Successful in 23s
- fix typo in INSTALLED_BIN variable name
- add GENERATE flag to optionally skip go generate
- add CREATE_SYSTEM_RESOURCES flag for user/dir creation control
- make GIT_VERSION optional with ?= operator
- add informative messages for skipped operations
2025-06-30 08:27:14 +03:00
d77ca4c384 feat: config command
All checks were successful
Pre-commit / pre-commit (pull_request) Successful in 5m5s
Update alr-git / changelog (push) Successful in 27s
2025-06-29 21:26:00 +03:00
6355f25089 feat: add ability to remove build_deps
All checks were successful
Pre-commit / pre-commit (pull_request) Successful in 5m36s
Update alr-git / changelog (push) Successful in 26s
2025-06-28 20:19:07 +03:00
a83561b6a5 fix: implement dirlfs to ignore symlinks
All checks were successful
Pre-commit / pre-commit (pull_request) Successful in 5m16s
Update alr-git / changelog (push) Successful in 25s
2025-06-28 01:01:06 +03:00
4b06809a39 fix: quote files-find output and fail on pattern not exists (#123)
All checks were successful
Update alr-git / changelog (push) Successful in 24s
closes #122
closes #121

Reviewed-on: #123
Co-authored-by: Maxim Slipenko <no-reply@maxim.slipenko.com>
Co-committed-by: Maxim Slipenko <no-reply@maxim.slipenko.com>
2025-06-27 20:22:10 +00:00
401c41160c chore: pass all options to download
All checks were successful
Pre-commit / pre-commit (pull_request) Successful in 5m26s
Update alr-git / changelog (push) Successful in 24s
2025-06-25 19:52:54 +03:00
5e1eeabd04 chore: simplify dlcache initialization
All checks were successful
Pre-commit / pre-commit (pull_request) Successful in 5m31s
Update alr-git / changelog (push) Successful in 23s
2025-06-25 19:18:11 +03:00
db19133254 fix: correct handling opts.PostprocDisabled
All checks were successful
Pre-commit / pre-commit (pull_request) Successful in 5m35s
Update alr-git / changelog (push) Successful in 29s
2025-06-25 08:07:58 +03:00
29 changed files with 954 additions and 241 deletions

View File

@ -1,16 +1,21 @@
NAME := alr NAME := alr
GIT_VERSION = $(shell git describe --tags ) GIT_VERSION ?= $(shell git describe --tags )
IGNORE_ROOT_CHECK ?= 0 IGNORE_ROOT_CHECK ?= 0
DESTDIR ?= DESTDIR ?=
PREFIX ?= /usr/local PREFIX ?= /usr/local
BIN := ./$(NAME) BIN := ./$(NAME)
INSTALED_BIN := $(DESTDIR)/$(PREFIX)/bin/$(NAME) INSTALLED_BIN := $(DESTDIR)/$(PREFIX)/bin/$(NAME)
COMPLETIONS_DIR := ./scripts/completion COMPLETIONS_DIR := ./scripts/completion
BASH_COMPLETION := $(COMPLETIONS_DIR)/bash BASH_COMPLETION := $(COMPLETIONS_DIR)/bash
ZSH_COMPLETION := $(COMPLETIONS_DIR)/zsh ZSH_COMPLETION := $(COMPLETIONS_DIR)/zsh
INSTALLED_BASH_COMPLETION := $(DESTDIR)$(PREFIX)/share/bash-completion/completions/$(NAME) INSTALLED_BASH_COMPLETION := $(DESTDIR)$(PREFIX)/share/bash-completion/completions/$(NAME)
INSTALLED_ZSH_COMPLETION := $(DESTDIR)$(PREFIX)/share/zsh/site-functions/_$(NAME) INSTALLED_ZSH_COMPLETION := $(DESTDIR)$(PREFIX)/share/zsh/site-functions/_$(NAME)
GENERATE ?= 1
CREATE_SYSTEM_RESOURCES ?= 1
ROOT_DIRS := /var/cache/alr /etc/alr
ADD_LICENSE_BIN := go run github.com/google/addlicense@4caba19b7ed7818bb86bc4cd20411a246aa4a524 ADD_LICENSE_BIN := go run github.com/google/addlicense@4caba19b7ed7818bb86bc4cd20411a246aa4a524
GOLANGCI_LINT_BIN := go run github.com/golangci/golangci-lint/cmd/golangci-lint@v1.63.4 GOLANGCI_LINT_BIN := go run github.com/golangci/golangci-lint/cmd/golangci-lint@v1.63.4
XGOTEXT_BIN := go run github.com/Tom5521/xgotext@v1.2.0 XGOTEXT_BIN := go run github.com/Tom5521/xgotext@v1.2.0
@ -21,7 +26,11 @@ build: check-no-root $(BIN)
export CGO_ENABLED := 0 export CGO_ENABLED := 0
$(BIN): $(BIN):
ifeq ($(GENERATE),1)
go generate ./... go generate ./...
else
@echo "Skipping go generate (GENERATE=0)"
endif
go build -ldflags="-X 'gitea.plemya-x.ru/Plemya-x/ALR/internal/config.Version=$(GIT_VERSION)'" -o $@ go build -ldflags="-X 'gitea.plemya-x.ru/Plemya-x/ALR/internal/config.Version=$(GIT_VERSION)'" -o $@
check-no-root: check-no-root:
@ -32,20 +41,26 @@ check-no-root:
fi fi
install: \ install: \
$(INSTALED_BIN) \ $(INSTALLED_BIN) \
$(INSTALLED_BASH_COMPLETION) \ $(INSTALLED_BASH_COMPLETION) \
$(INSTALLED_ZSH_COMPLETION) $(INSTALLED_ZSH_COMPLETION)
@echo "Installation done!" @echo "Installation done!"
$(INSTALED_BIN): $(BIN) $(INSTALLED_BIN): $(BIN)
install -Dm755 $< $@ install -Dm755 $< $@
setcap cap_setuid,cap_setgid+ep $(INSTALED_BIN) ifeq ($(CREATE_SYSTEM_RESOURCES),1)
setcap cap_setuid,cap_setgid+ep $(INSTALLED_BIN)
@if id alr >/dev/null 2>&1; then \ @if id alr >/dev/null 2>&1; then \
echo "User 'alr' already exists. Skipping."; \ echo "User 'alr' already exists. Skipping."; \
else \ else \
useradd -r -s /usr/sbin/nologin alr; \ useradd -r -s /usr/sbin/nologin alr; \
fi fi
install -d -o alr -g alr -m 755 /var/cache/alr /etc/alr @for dir in $(ROOT_DIRS); do \
install -d -o alr -g alr -m 755 $$dir; \
done
else
@echo "Skipping user and root dir creation (CREATE_SYSTEM_RESOURCES=0)"
endif
$(INSTALLED_BASH_COMPLETION): $(BASH_COMPLETION) $(INSTALLED_BASH_COMPLETION): $(BASH_COMPLETION)
install -Dm755 $< $@ install -Dm755 $< $@
@ -55,7 +70,7 @@ $(INSTALLED_ZSH_COMPLETION): $(ZSH_COMPLETION)
uninstall: uninstall:
rm -f \ rm -f \
$(INSTALED_BIN) \ $(INSTALLED_BIN) \
$(INSTALLED_BASH_COMPLETION) \ $(INSTALLED_BASH_COMPLETION) \
$(INSTALLED_ZSH_COMPLETION) $(INSTALLED_ZSH_COMPLETION)

View File

@ -11,7 +11,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="33.5" y="15" fill="#010101" fill-opacity=".3">coverage</text> <text x="33.5" y="15" fill="#010101" fill-opacity=".3">coverage</text>
<text x="33.5" y="14">coverage</text> <text x="33.5" y="14">coverage</text>
<text x="86" y="15" fill="#010101" fill-opacity=".3">19.7%</text> <text x="86" y="15" fill="#010101" fill-opacity=".3">19.2%</text>
<text x="86" y="14">19.7%</text> <text x="86" y="14">19.2%</text>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 926 B

After

Width:  |  Height:  |  Size: 926 B

227
config.go Normal file
View File

@ -0,0 +1,227 @@
// ALR - Any Linux Repository
// Copyright (C) 2025 The ALR Authors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package main
import (
"fmt"
"strconv"
"strings"
"github.com/goccy/go-yaml"
"github.com/leonelquinteros/gotext"
"github.com/urfave/cli/v2"
"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/utils"
)
func ConfigCmd() *cli.Command {
return &cli.Command{
Name: "config",
Usage: gotext.Get("Manage config"),
Subcommands: []*cli.Command{
ShowCmd(),
SetConfig(),
GetConfig(),
},
}
}
func ShowCmd() *cli.Command {
return &cli.Command{
Name: "show",
Usage: gotext.Get("Show config"),
BashComplete: cliutils.BashCompleteWithError(func(c *cli.Context) error {
return nil
}),
Action: func(c *cli.Context) error {
deps, err := appbuilder.
New(c.Context).
WithConfig().
Build()
if err != nil {
return err
}
defer deps.Defer()
content, err := deps.Cfg.ToYAML()
if err != nil {
return err
}
fmt.Println(content)
return nil
},
}
}
var configKeys = []string{
"rootCmd",
"useRootCmd",
"pagerStyle",
"autoPull",
"logLevel",
"ignorePkgUpdates",
}
func SetConfig() *cli.Command {
return &cli.Command{
Name: "set",
Usage: gotext.Get("Set config value"),
ArgsUsage: gotext.Get("<key> <value>"),
BashComplete: cliutils.BashCompleteWithError(func(c *cli.Context) error {
if c.Args().Len() == 0 {
for _, key := range configKeys {
fmt.Println(key)
}
return nil
}
return nil
}),
Action: utils.RootNeededAction(func(c *cli.Context) error {
if c.Args().Len() < 2 {
return cliutils.FormatCliExit("missing args", nil)
}
key := c.Args().Get(0)
value := c.Args().Get(1)
deps, err := appbuilder.
New(c.Context).
WithConfig().
Build()
if err != nil {
return err
}
defer deps.Defer()
switch key {
case "rootCmd":
deps.Cfg.System.SetRootCmd(value)
case "useRootCmd":
boolValue, err := strconv.ParseBool(value)
if err != nil {
return cliutils.FormatCliExit(gotext.Get("invalid boolean value for %s: %s", key, value), err)
}
deps.Cfg.System.SetUseRootCmd(boolValue)
case "pagerStyle":
deps.Cfg.System.SetPagerStyle(value)
case "autoPull":
boolValue, err := strconv.ParseBool(value)
if err != nil {
return cliutils.FormatCliExit(gotext.Get("invalid boolean value for %s: %s", key, value), err)
}
deps.Cfg.System.SetAutoPull(boolValue)
case "logLevel":
deps.Cfg.System.SetLogLevel(value)
case "ignorePkgUpdates":
var updates []string
if value != "" {
updates = strings.Split(value, ",")
for i, update := range updates {
updates[i] = strings.TrimSpace(update)
}
}
deps.Cfg.System.SetIgnorePkgUpdates(updates)
case "repo", "repos":
return cliutils.FormatCliExit(gotext.Get("use 'repo add/remove' commands to manage repositories"), nil)
default:
return cliutils.FormatCliExit(gotext.Get("unknown config key: %s", key), nil)
}
if err := deps.Cfg.System.Save(); err != nil {
return cliutils.FormatCliExit(gotext.Get("failed to save config"), err)
}
fmt.Println(gotext.Get("Successfully set %s = %s", key, value))
return nil
}),
}
}
func GetConfig() *cli.Command {
return &cli.Command{
Name: "get",
Usage: gotext.Get("Get config value"),
ArgsUsage: gotext.Get("<key>"),
BashComplete: cliutils.BashCompleteWithError(func(c *cli.Context) error {
if c.Args().Len() == 0 {
for _, key := range configKeys {
fmt.Println(key)
}
return nil
}
return nil
}),
Action: func(c *cli.Context) error {
deps, err := appbuilder.
New(c.Context).
WithConfig().
Build()
if err != nil {
return err
}
defer deps.Defer()
if c.Args().Len() == 0 {
content, err := deps.Cfg.ToYAML()
if err != nil {
return cliutils.FormatCliExit("failed to serialize config", err)
}
fmt.Print(content)
return nil
}
key := c.Args().Get(0)
switch key {
case "rootCmd":
fmt.Println(deps.Cfg.RootCmd())
case "useRootCmd":
fmt.Println(deps.Cfg.UseRootCmd())
case "pagerStyle":
fmt.Println(deps.Cfg.PagerStyle())
case "autoPull":
fmt.Println(deps.Cfg.AutoPull())
case "logLevel":
fmt.Println(deps.Cfg.LogLevel())
case "ignorePkgUpdates":
updates := deps.Cfg.IgnorePkgUpdates()
if len(updates) == 0 {
fmt.Println("[]")
} else {
fmt.Println(strings.Join(updates, ", "))
}
case "repo", "repos":
repos := deps.Cfg.Repos()
if len(repos) == 0 {
fmt.Println("[]")
} else {
repoData, err := yaml.Marshal(repos)
if err != nil {
return cliutils.FormatCliExit("failed to serialize repos", err)
}
fmt.Print(string(repoData))
}
default:
return cliutils.FormatCliExit(gotext.Get("unknown config key: %s", key), nil)
}
return nil
},
}
}

View File

@ -66,7 +66,7 @@ func TestE2EAlrAddRepo(t *testing.T) {
"cat /etc/alr/alr.toml", "cat /etc/alr/alr.toml",
), e2e.WithExecOptionStdout(&buf)) ), e2e.WithExecOptionStdout(&buf))
assert.NoError(t, err) assert.NoError(t, err)
assert.Contains(t, buf.String(), "rootCmd") assert.Contains(t, buf.String(), "repo = []")
}, },
) )
} }

View File

@ -0,0 +1,47 @@
// ALR - Any Linux Repository
// Copyright (C) 2025 The ALR Authors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//go:build e2e
package e2etests_test
import (
"testing"
"github.com/efficientgo/e2e"
)
func TestE2EIssue95ConfigCommand(t *testing.T) {
dockerMultipleRun(
t,
"issue-95-config-command",
COMMON_SYSTEMS,
func(t *testing.T, r e2e.Runnable) {
defaultPrepare(t, r)
execShouldNoError(t, r, "sh", "-c", "alr config show | grep \"autoPull: true\"")
execShouldNoError(t, r, "sh", "-c", "alr config get | grep \"autoPull: true\"")
execShouldError(t, r, "sh", "-c", "cat /etc/alr/alr.toml | grep \"autoPull\"")
execShouldNoError(t, r, "alr", "config", "get", "autoPull")
execShouldError(t, r, "alr", "config", "set", "autoPull")
execShouldNoError(t, r, "sudo", "alr", "config", "set", "autoPull", "false")
execShouldNoError(t, r, "sh", "-c", "alr config show | grep \"autoPull: false\"")
execShouldNoError(t, r, "sh", "-c", "alr config get | grep \"autoPull: false\"")
execShouldNoError(t, r, "sh", "-c", "cat /etc/alr/alr.toml | grep \"autoPull = false\"")
execShouldNoError(t, r, "alr", "config", "set", "autoPull", "true")
execShouldNoError(t, r, "sh", "-c", "cat /etc/alr/alr.toml | grep \"autoPull = true\"")
},
)
}

25
go.mod
View File

@ -29,7 +29,7 @@ require (
github.com/mholt/archiver/v4 v4.0.0-alpha.8 github.com/mholt/archiver/v4 v4.0.0-alpha.8
github.com/mitchellh/mapstructure v1.5.0 github.com/mitchellh/mapstructure v1.5.0
github.com/muesli/reflow v0.3.0 github.com/muesli/reflow v0.3.0
github.com/pelletier/go-toml/v2 v2.1.0 github.com/pelletier/go-toml/v2 v2.2.4
github.com/stretchr/testify v1.10.0 github.com/stretchr/testify v1.10.0
github.com/tailscale/goexpect v0.0.0-20210902213824-6e8c725cea41 github.com/tailscale/goexpect v0.0.0-20210902213824-6e8c725cea41
github.com/urfave/cli/v2 v2.25.7 github.com/urfave/cli/v2 v2.25.7
@ -37,7 +37,7 @@ require (
go.elara.ws/vercmp v0.0.0-20230622214216-0b2b067575c4 go.elara.ws/vercmp v0.0.0-20230622214216-0b2b067575c4
golang.org/x/crypto v0.36.0 golang.org/x/crypto v0.36.0
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
golang.org/x/sys v0.31.0 golang.org/x/sys v0.33.0
golang.org/x/text v0.23.0 golang.org/x/text v0.23.0
modernc.org/sqlite v1.25.0 modernc.org/sqlite v1.25.0
mvdan.cc/sh/v3 v3.10.0 mvdan.cc/sh/v3 v3.10.0
@ -75,8 +75,11 @@ require (
github.com/emirpasic/gods v1.18.1 // indirect github.com/emirpasic/gods v1.18.1 // indirect
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/fatih/color v1.7.0 // indirect github.com/fatih/color v1.7.0 // indirect
github.com/fatih/structs v1.1.0 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
github.com/gobwas/glob v0.2.3 // indirect github.com/gobwas/glob v0.2.3 // indirect
github.com/goccy/go-json v0.8.1 // indirect github.com/goccy/go-json v0.8.1 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
@ -84,7 +87,7 @@ require (
github.com/golang/snappy v0.0.4 // indirect github.com/golang/snappy v0.0.4 // indirect
github.com/google/goterm v0.0.0-20190703233501-fc88cf888a3f // indirect github.com/google/goterm v0.0.0-20190703233501-fc88cf888a3f // indirect
github.com/google/rpmpack v0.6.1-0.20240329070804-c2247cbb881a // indirect github.com/google/rpmpack v0.6.1-0.20240329070804-c2247cbb881a // indirect
github.com/google/uuid v1.4.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/goreleaser/chglog v0.6.1 // indirect github.com/goreleaser/chglog v0.6.1 // indirect
github.com/goreleaser/fileglob v1.3.0 // indirect github.com/goreleaser/fileglob v1.3.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect
@ -98,6 +101,15 @@ require (
github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/compress v1.17.11 // indirect github.com/klauspost/compress v1.17.11 // indirect
github.com/klauspost/pgzip v1.2.6 // indirect github.com/klauspost/pgzip v1.2.6 // indirect
github.com/knadh/koanf/maps v0.1.2 // indirect
github.com/knadh/koanf/parsers/json v1.0.0 // indirect
github.com/knadh/koanf/parsers/toml/v2 v2.2.0 // indirect
github.com/knadh/koanf/providers/confmap v1.0.0 // indirect
github.com/knadh/koanf/providers/env v1.1.0 // indirect
github.com/knadh/koanf/providers/file v1.2.0 // indirect
github.com/knadh/koanf/providers/rawbytes v1.0.0 // indirect
github.com/knadh/koanf/providers/structs v1.0.0 // indirect
github.com/knadh/koanf/v2 v2.2.1 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-localereader v0.0.1 // indirect
@ -121,7 +133,7 @@ require (
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
github.com/shopspring/decimal v1.3.1 // indirect github.com/shopspring/decimal v1.3.1 // indirect
github.com/skeema/knownhosts v1.3.0 // indirect github.com/skeema/knownhosts v1.3.0 // indirect
github.com/spf13/cast v1.6.0 // indirect github.com/spf13/cast v1.7.1 // indirect
github.com/syndtr/goleveldb v1.0.0 // indirect github.com/syndtr/goleveldb v1.0.0 // indirect
github.com/therootcompany/xz v1.0.1 // indirect github.com/therootcompany/xz v1.0.1 // indirect
github.com/ulikunitz/xz v0.5.12 // indirect github.com/ulikunitz/xz v0.5.12 // indirect
@ -132,11 +144,12 @@ require (
go4.org v0.0.0-20200411211856-f5505b9728dd // indirect go4.org v0.0.0-20200411211856-f5505b9728dd // indirect
golang.org/x/mod v0.19.0 // indirect golang.org/x/mod v0.19.0 // indirect
golang.org/x/net v0.38.0 // indirect golang.org/x/net v0.38.0 // indirect
golang.org/x/oauth2 v0.25.0 // indirect
golang.org/x/sync v0.12.0 // indirect golang.org/x/sync v0.12.0 // indirect
golang.org/x/term v0.30.0 // indirect golang.org/x/term v0.30.0 // indirect
golang.org/x/tools v0.23.0 // indirect golang.org/x/tools v0.23.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20241223144023-3abc09e42ca8 // indirect
google.golang.org/grpc v1.58.3 // indirect google.golang.org/grpc v1.67.3 // indirect
google.golang.org/protobuf v1.36.1 // indirect google.golang.org/protobuf v1.36.1 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect

62
go.sum
View File

@ -84,8 +84,8 @@ github.com/caarlos0/testfs v0.4.4/go.mod h1:bRN55zgG4XCUVVHZCeU+/Tz1Q6AxEJOEJTli
github.com/cavaliergopher/cpio v1.0.1 h1:KQFSeKmZhv0cr+kawA3a0xTQCU4QxXF1vhU7P7av2KM= github.com/cavaliergopher/cpio v1.0.1 h1:KQFSeKmZhv0cr+kawA3a0xTQCU4QxXF1vhU7P7av2KM=
github.com/cavaliergopher/cpio v1.0.1/go.mod h1:pBdaqQjnvXxdS/6CvNDwIANIFSP0xRKI16PX4xejRQc= github.com/cavaliergopher/cpio v1.0.1/go.mod h1:pBdaqQjnvXxdS/6CvNDwIANIFSP0xRKI16PX4xejRQc=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE= github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE=
github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU= github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU=
github.com/charmbracelet/bubbletea v1.2.4 h1:KN8aCViA0eps9SCOThb2/XPIlea3ANJLUkv3KnQRNCE= github.com/charmbracelet/bubbletea v1.2.4 h1:KN8aCViA0eps9SCOThb2/XPIlea3ANJLUkv3KnQRNCE=
@ -139,9 +139,13 @@ github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
@ -160,6 +164,8 @@ github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7
github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow= github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/goccy/go-json v0.8.1 h1:4/Wjm0JIJaTDm8K1KcGrLHJoa8EsJ13YWeX+6Kfq6uI= github.com/goccy/go-json v0.8.1 h1:4/Wjm0JIJaTDm8K1KcGrLHJoa8EsJ13YWeX+6Kfq6uI=
@ -212,8 +218,8 @@ github.com/google/rpmpack v0.6.1-0.20240329070804-c2247cbb881a/go.mod h1:uqVAUVQ
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
@ -273,6 +279,24 @@ github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo=
github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI=
github.com/knadh/koanf/parsers/json v1.0.0 h1:1pVR1JhMwbqSg5ICzU+surJmeBbdT4bQm7jjgnA+f8o=
github.com/knadh/koanf/parsers/json v1.0.0/go.mod h1:zb5WtibRdpxSoSJfXysqGbVxvbszdlroWDHGdDkkEYU=
github.com/knadh/koanf/parsers/toml/v2 v2.2.0 h1:2nV7tHYJ5OZy2BynQ4mOJ6k5bDqbbCzRERLUKBytz3A=
github.com/knadh/koanf/parsers/toml/v2 v2.2.0/go.mod h1:JpjTeK1Ge1hVX0wbof5DMCuDBriR8bWgeQP98eeOZpI=
github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE=
github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A=
github.com/knadh/koanf/providers/env v1.1.0 h1:U2VXPY0f+CsNDkvdsG8GcsnK4ah85WwWyJgef9oQMSc=
github.com/knadh/koanf/providers/env v1.1.0/go.mod h1:QhHHHZ87h9JxJAn2czdEl6pdkNnDh/JS1Vtsyt65hTY=
github.com/knadh/koanf/providers/file v1.2.0 h1:hrUJ6Y9YOA49aNu/RSYzOTFlqzXSCpmYIDXI7OJU6+U=
github.com/knadh/koanf/providers/file v1.2.0/go.mod h1:bp1PM5f83Q+TOUu10J/0ApLBd9uIzg+n9UgthfY+nRA=
github.com/knadh/koanf/providers/rawbytes v1.0.0 h1:MrKDh/HksJlKJmaZjgs4r8aVBb/zsJyc/8qaSnzcdNI=
github.com/knadh/koanf/providers/rawbytes v1.0.0/go.mod h1:KxwYJf1uezTKy6PBtfE+m725NGp4GPVA7XoNTJ/PtLo=
github.com/knadh/koanf/providers/structs v1.0.0 h1:DznjB7NQykhqCar2LvNug3MuxEQsZ5KvfgMbio+23u4=
github.com/knadh/koanf/providers/structs v1.0.0/go.mod h1:kjo5TFtgpaZORlpoJqcbeLowM2cINodv8kX+oFAeQ1w=
github.com/knadh/koanf/v2 v2.2.1 h1:jaleChtw85y3UdBnI0wCqcg1sj1gPoz6D3caGNHtrNE=
github.com/knadh/koanf/v2 v2.2.1/go.mod h1:PSFru3ufQgTsI7IF+95rf9s8XA1+aHxKuO/W+dPoHEY=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
@ -341,8 +365,10 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0= github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0=
github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
@ -388,19 +414,15 @@ github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+
github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY= github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY=
github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60= github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
@ -500,8 +522,8 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70=
golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -541,6 +563,8 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
@ -601,8 +625,6 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@ -616,8 +638,8 @@ google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvx
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= google.golang.org/genproto/googleapis/rpc v0.0.0-20241223144023-3abc09e42ca8 h1:TqExAhdPaB60Ux47Cn0oLV07rGnxZzIsaRhQaqS666A=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= google.golang.org/genproto/googleapis/rpc v0.0.0-20241223144023-3abc09e42ca8/go.mod h1:lcTa1sDdWEIHMWlITnIczmw5w60CF9ffkb8Z+DVmmjA=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@ -625,8 +647,8 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= google.golang.org/grpc v1.67.3 h1:OgPcDAFKHnH8X3O4WcO4XUc8GRDeKsKReqbQtiCj7N8=
google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/grpc v1.67.3/go.mod h1:YGaHCc6Oap+FzBJTZLBzkGSYt/cvGPFTPxkn7QfSU8s=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=

View File

@ -214,6 +214,8 @@ type CheckerExecutor interface {
type InstallerExecutor interface { type InstallerExecutor interface {
InstallLocal(paths []string, opts *manager.Opts) error InstallLocal(paths []string, opts *manager.Opts) error
Install(pkgs []string, opts *manager.Opts) error Install(pkgs []string, opts *manager.Opts) error
Remove(pkgs []string, opts *manager.Opts) error
RemoveAlreadyInstalled(pkgs []string) ([]string, error) RemoveAlreadyInstalled(pkgs []string) ([]string, error)
} }
@ -408,7 +410,7 @@ func (b *Builder) BuildPackage(
sources, checksums = removeDuplicatesSources(sources, checksums) sources, checksums = removeDuplicatesSources(sources, checksums)
slog.Debug("installBuildDeps") slog.Debug("installBuildDeps")
alrBuildDeps, err := b.installBuildDeps(ctx, input, buildDepends) alrBuildDeps, installedBuildDeps, err := b.installBuildDeps(ctx, input, buildDepends)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -477,9 +479,39 @@ func (b *Builder) BuildPackage(
builtDeps = removeDuplicates(append(builtDeps, res...)) builtDeps = removeDuplicates(append(builtDeps, res...))
err = b.removeBuildDeps(ctx, input, installedBuildDeps)
if err != nil {
return nil, err
}
return builtDeps, nil return builtDeps, nil
} }
func (b *Builder) removeBuildDeps(ctx context.Context, input interface {
BuildOptsProvider
}, deps []string,
) error {
if len(deps) > 0 {
remove, err := cliutils.YesNoPrompt(ctx, gotext.Get("Would you like to remove the build dependencies?"), input.BuildOpts().Interactive, false)
if err != nil {
return err
}
if remove {
err = b.installerExecutor.Remove(
deps,
&manager.Opts{
NoConfirm: !input.BuildOpts().Interactive,
},
)
if err != nil {
return err
}
}
}
return nil
}
type InstallPkgsArgs struct { type InstallPkgsArgs struct {
BuildArgs BuildArgs
AlrPkgs []alrsh.Package AlrPkgs []alrsh.Package
@ -608,20 +640,22 @@ func (i *Builder) installBuildDeps(
PkgFormatProvider PkgFormatProvider
}, },
pkgs []string, pkgs []string,
) ([]*BuiltDep, error) { ) ([]*BuiltDep, []string, error) {
var builtDeps []*BuiltDep var builtDeps []*BuiltDep
var deps []string
var err error
if len(pkgs) > 0 { if len(pkgs) > 0 {
deps, err := i.installerExecutor.RemoveAlreadyInstalled(pkgs) deps, err = i.installerExecutor.RemoveAlreadyInstalled(pkgs)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
builtDeps, err = i.InstallPkgs(ctx, input, deps) // Устанавливаем выбранные пакеты builtDeps, err = i.InstallPkgs(ctx, input, deps) // Устанавливаем выбранные пакеты
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
} }
return builtDeps, nil return builtDeps, deps, nil
} }
func (i *Builder) installOptDeps( func (i *Builder) installOptDeps(

View File

@ -36,6 +36,10 @@ func (i *Installer) Install(pkgs []string, opts *manager.Opts) error {
return i.mgr.Install(opts, pkgs...) return i.mgr.Install(opts, pkgs...)
} }
func (i *Installer) Remove(pkgs []string, opts *manager.Opts) error {
return i.mgr.Remove(opts, pkgs...)
}
func (i *Installer) RemoveAlreadyInstalled(pkgs []string) ([]string, error) { func (i *Installer) RemoveAlreadyInstalled(pkgs []string) ([]string, error) {
filteredPackages := []string{} filteredPackages := []string{}

View File

@ -70,6 +70,17 @@ func (s *InstallerRPCServer) Install(args *InstallArgs, reply *struct{}) error {
return s.Impl.Install(args.PackagesOrPaths, args.Opts) return s.Impl.Install(args.PackagesOrPaths, args.Opts)
} }
func (r *InstallerRPC) Remove(pkgs []string, opts *manager.Opts) error {
return r.client.Call("Plugin.Remove", &InstallArgs{
PackagesOrPaths: pkgs,
Opts: opts,
}, nil)
}
func (s *InstallerRPCServer) Remove(args *InstallArgs, reply *struct{}) error {
return s.Impl.Remove(args.PackagesOrPaths, args.Opts)
}
func (r *InstallerRPC) RemoveAlreadyInstalled(paths []string) ([]string, error) { func (r *InstallerRPC) RemoveAlreadyInstalled(paths []string) ([]string, error) {
var val []string var val []string
err := r.client.Call("Plugin.RemoveAlreadyInstalled", paths, &val) err := r.client.Call("Plugin.RemoveAlreadyInstalled", paths, &val)

View File

@ -74,7 +74,7 @@ func (s *SourceDownloader) DownloadSources(
} }
} }
opts.DlCache = dlcache.New(s.cfg) opts.DlCache = dlcache.New(s.cfg.GetPaths().CacheDir)
err := dl.Download(ctx, opts) err := dl.Download(ctx, opts)
if err != nil { if err != nil {

View File

@ -20,13 +20,12 @@
package config package config
import ( import (
"log/slog" "fmt"
"os"
"path/filepath" "path/filepath"
"reflect"
"github.com/caarlos0/env" "github.com/goccy/go-yaml"
"github.com/pelletier/go-toml/v2" "github.com/knadh/koanf/providers/confmap"
"github.com/knadh/koanf/v2"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/constants" "gitea.plemya-x.ru/Plemya-x/ALR/internal/constants"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
@ -35,74 +34,65 @@ import (
type ALRConfig struct { type ALRConfig struct {
cfg *types.Config cfg *types.Config
paths *Paths paths *Paths
}
var defaultConfig = &types.Config{ System *SystemConfig
RootCmd: "sudo", env *EnvConfig
UseRootCmd: true,
PagerStyle: "native",
IgnorePkgUpdates: []string{},
AutoPull: true,
Repos: []types.Repo{},
} }
func New() *ALRConfig { func New() *ALRConfig {
return &ALRConfig{} return &ALRConfig{
System: NewSystemConfig(),
env: NewEnvConfig(),
}
} }
func readConfig(path string) (*types.Config, error) { func defaultConfigKoanf() *koanf.Koanf {
file, err := os.Open(path) k := koanf.New(".")
if err != nil { defaults := map[string]interface{}{
return nil, err "rootCmd": "sudo",
"useRootCmd": true,
"pagerStyle": "native",
"ignorePkgUpdates": []string{},
"logLevel": "info",
"autoPull": true,
"repos": []types.Repo{},
} }
defer file.Close() if err := k.Load(confmap.Provider(defaults, "."), nil); err != nil {
panic(k)
config := types.Config{}
if err := toml.NewDecoder(file).Decode(&config); err != nil {
return nil, err
}
return &config, nil
}
func mergeStructs(dst, src interface{}) {
srcVal := reflect.ValueOf(src)
if srcVal.IsNil() {
return
}
srcVal = srcVal.Elem()
dstVal := reflect.ValueOf(dst).Elem()
for i := range srcVal.NumField() {
srcField := srcVal.Field(i)
srcFieldName := srcVal.Type().Field(i).Name
dstField := dstVal.FieldByName(srcFieldName)
if dstField.IsValid() && dstField.CanSet() {
dstField.Set(srcField)
}
} }
return k
} }
func (c *ALRConfig) Load() error { func (c *ALRConfig) Load() error {
systemConfig, err := readConfig( config := types.Config{}
constants.SystemConfigPath,
) merged := koanf.New(".")
if err != nil {
slog.Debug("Cannot read system config", "err", err) if err := c.System.Load(); err != nil {
return fmt.Errorf("failed to load system config: %w", err)
} }
config := &types.Config{} if err := c.env.Load(); err != nil {
return fmt.Errorf("failed to load env config: %w", err)
mergeStructs(config, defaultConfig)
mergeStructs(config, systemConfig)
err = env.Parse(config)
if err != nil {
return err
} }
c.cfg = config systemK := c.System.koanf()
envK := c.env.koanf()
if err := merged.Merge(defaultConfigKoanf()); err != nil {
return fmt.Errorf("failed to merge default config: %w", err)
}
if err := merged.Merge(systemK); err != nil {
return fmt.Errorf("failed to merge system config: %w", err)
}
if err := merged.Merge(envK); err != nil {
return fmt.Errorf("failed to merge env config: %w", err)
}
if err := merged.Unmarshal("", &config); err != nil {
return fmt.Errorf("failed to unmarshal merged config: %w", err)
}
c.cfg = &config
c.paths = &Paths{} c.paths = &Paths{}
c.paths.UserConfigPath = constants.SystemConfigPath c.paths.UserConfigPath = constants.SystemConfigPath
@ -110,52 +100,24 @@ func (c *ALRConfig) Load() error {
c.paths.RepoDir = filepath.Join(c.paths.CacheDir, "repo") c.paths.RepoDir = filepath.Join(c.paths.CacheDir, "repo")
c.paths.PkgsDir = filepath.Join(c.paths.CacheDir, "pkgs") c.paths.PkgsDir = filepath.Join(c.paths.CacheDir, "pkgs")
c.paths.DBPath = filepath.Join(c.paths.CacheDir, "db") c.paths.DBPath = filepath.Join(c.paths.CacheDir, "db")
// c.initPaths()
return nil return nil
} }
func (c *ALRConfig) RootCmd() string { func (c *ALRConfig) ToYAML() (string, error) {
return c.cfg.RootCmd data, err := yaml.Marshal(c.cfg)
}
func (c *ALRConfig) PagerStyle() string {
return c.cfg.PagerStyle
}
func (c *ALRConfig) AutoPull() bool {
return c.cfg.AutoPull
}
func (c *ALRConfig) Repos() []types.Repo {
return c.cfg.Repos
}
func (c *ALRConfig) SetRepos(repos []types.Repo) {
c.cfg.Repos = repos
}
func (c *ALRConfig) IgnorePkgUpdates() []string {
return c.cfg.IgnorePkgUpdates
}
func (c *ALRConfig) LogLevel() string {
return c.cfg.LogLevel
}
func (c *ALRConfig) UseRootCmd() bool {
return c.cfg.UseRootCmd
}
func (c *ALRConfig) GetPaths() *Paths {
return c.paths
}
func (c *ALRConfig) SaveUserConfig() error {
f, err := os.Create(c.paths.UserConfigPath)
if err != nil { if err != nil {
return err return "", err
} }
return string(data), nil
return toml.NewEncoder(f).Encode(c.cfg)
} }
func (c *ALRConfig) RootCmd() string { return c.cfg.RootCmd }
func (c *ALRConfig) PagerStyle() string { return c.cfg.PagerStyle }
func (c *ALRConfig) AutoPull() bool { return c.cfg.AutoPull }
func (c *ALRConfig) Repos() []types.Repo { return c.cfg.Repos }
func (c *ALRConfig) SetRepos(repos []types.Repo) { c.System.SetRepos(repos) }
func (c *ALRConfig) IgnorePkgUpdates() []string { return c.cfg.IgnorePkgUpdates }
func (c *ALRConfig) LogLevel() string { return c.cfg.LogLevel }
func (c *ALRConfig) UseRootCmd() bool { return c.cfg.UseRootCmd }
func (c *ALRConfig) GetPaths() *Paths { return c.paths }

View File

@ -0,0 +1,76 @@
// ALR - Any Linux Repository
// Copyright (C) 2025 The ALR Authors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package config
import (
"strings"
"github.com/knadh/koanf/providers/env"
"github.com/knadh/koanf/v2"
"golang.org/x/text/cases"
"golang.org/x/text/language"
)
type EnvConfig struct {
k *koanf.Koanf
}
func NewEnvConfig() *EnvConfig {
return &EnvConfig{
k: koanf.New("."),
}
}
func (c *EnvConfig) koanf() *koanf.Koanf {
return c.k
}
func (c *EnvConfig) Load() error {
allowedKeys := map[string]struct{}{
"ALR_LOG_LEVEL": {},
"ALR_PAGER_STYLE": {},
"ALR_AUTO_PULL": {},
}
err := c.k.Load(env.Provider("ALR_", ".", func(s string) string {
_, ok := allowedKeys[s]
if !ok {
return ""
}
withoutPrefix := strings.TrimPrefix(s, "ALR_")
lowered := strings.ToLower(withoutPrefix)
dotted := strings.ReplaceAll(lowered, "__", ".")
parts := strings.Split(dotted, ".")
for i, part := range parts {
if strings.Contains(part, "_") {
parts[i] = toCamelCase(part)
}
}
return strings.Join(parts, ".")
}), nil)
return err
}
func toCamelCase(s string) string {
parts := strings.Split(s, "_")
for i := 1; i < len(parts); i++ {
if len(parts[i]) > 0 {
parts[i] = cases.Title(language.Und, cases.NoLower).String(parts[i])
}
}
return strings.Join(parts, "")
}

View File

@ -21,9 +21,10 @@ package config
// Paths contains various paths used by ALR // Paths contains various paths used by ALR
type Paths struct { type Paths struct {
UserConfigPath string SystemConfigPath string
CacheDir string UserConfigPath string
RepoDir string CacheDir string
PkgsDir string RepoDir string
DBPath string PkgsDir string
DBPath string
} }

View File

@ -0,0 +1,144 @@
// ALR - Any Linux Repository
// Copyright (C) 2025 The ALR Authors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package config
import (
"encoding/json"
"errors"
"fmt"
"os"
ktoml "github.com/knadh/koanf/parsers/toml/v2"
"github.com/knadh/koanf/providers/file"
"github.com/knadh/koanf/v2"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/constants"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
)
type SystemConfig struct {
k *koanf.Koanf
cfg *types.Config
}
func NewSystemConfig() *SystemConfig {
return &SystemConfig{
k: koanf.New("."),
cfg: &types.Config{},
}
}
func (c *SystemConfig) koanf() *koanf.Koanf {
return c.k
}
func (c *SystemConfig) Load() error {
if _, err := os.Stat(constants.SystemConfigPath); errors.Is(err, os.ErrNotExist) {
return nil
}
if err := c.k.Load(file.Provider(constants.SystemConfigPath), ktoml.Parser()); err != nil {
return err
}
return c.k.Unmarshal("", c.cfg)
}
func (c *SystemConfig) Save() error {
bytes, err := c.k.Marshal(ktoml.Parser())
if err != nil {
return fmt.Errorf("failed to marshal config: %w", err)
}
file, err := os.Create(constants.SystemConfigPath)
if err != nil {
return fmt.Errorf("failed to create config file: %w", err)
}
defer func() {
if cerr := file.Close(); cerr != nil && err == nil {
err = cerr
}
}()
if _, err := file.Write(bytes); err != nil {
return fmt.Errorf("failed to write config: %w", err)
}
if err := file.Sync(); err != nil {
return fmt.Errorf("failed to sync config: %w", err)
}
return nil
}
func (c *SystemConfig) SetRootCmd(v string) {
err := c.k.Set("rootCmd", v)
if err != nil {
panic(err)
}
}
func (c *SystemConfig) SetUseRootCmd(v bool) {
err := c.k.Set("useRootCmd", v)
if err != nil {
panic(err)
}
}
func (c *SystemConfig) SetPagerStyle(v string) {
err := c.k.Set("pagerStyle", v)
if err != nil {
panic(err)
}
}
func (c *SystemConfig) SetIgnorePkgUpdates(v []string) {
err := c.k.Set("ignorePkgUpdates", v)
if err != nil {
panic(err)
}
}
func (c *SystemConfig) SetAutoPull(v bool) {
err := c.k.Set("autoPull", v)
if err != nil {
panic(err)
}
}
func (c *SystemConfig) SetLogLevel(v string) {
err := c.k.Set("logLevel", v)
if err != nil {
panic(err)
}
}
func (c *SystemConfig) SetRepos(v []types.Repo) {
b, err := json.Marshal(v)
if err != nil {
panic(err)
}
var m []interface{}
err = json.Unmarshal(b, &m)
if err != nil {
panic(err)
}
err = c.k.Set("repo", m)
if err != nil {
panic(err)
}
}

View File

@ -0,0 +1,53 @@
// ALR - Any Linux Repository
// Copyright (C) 2025 The ALR Authors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package helpers
import (
"io/fs"
"os"
"path/filepath"
)
// dirLfs implements fs.FS like os.DirFS but uses LStat instead of Stat.
// This means symbolic links are treated as links themselves rather than
// being followed to their targets.
type dirLfs struct {
fs.FS
dir string
}
func NewDirLFS(dir string) *dirLfs {
return &dirLfs{
FS: os.DirFS(dir),
dir: dir,
}
}
func (d *dirLfs) Stat(name string) (fs.FileInfo, error) {
if !fs.ValidPath(name) {
return nil, &fs.PathError{Op: "stat", Path: name, Err: fs.ErrInvalid}
}
fullPath := filepath.Join(d.dir, filepath.FromSlash(name))
info, err := os.Lstat(fullPath)
if err != nil {
return nil, &fs.PathError{Op: "stat", Path: name, Err: err}
}
return info, nil
}

View File

@ -18,13 +18,13 @@ package helpers
import ( import (
"fmt" "fmt"
"log/slog"
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
"github.com/bmatcuk/doublestar/v4" "github.com/bmatcuk/doublestar/v4"
"mvdan.cc/sh/v3/interp" "mvdan.cc/sh/v3/interp"
"mvdan.cc/sh/v3/syntax"
) )
func matchNamePattern(name, pattern string) bool { func matchNamePattern(name, pattern string) bool {
@ -46,10 +46,15 @@ func validateDir(dirPath, commandName string) error {
return nil return nil
} }
func outputFiles(hc interp.HandlerContext, files []string) { func outputFiles(hc interp.HandlerContext, files []string) error {
for _, file := range files { for _, file := range files {
fmt.Fprintln(hc.Stdout, file) v, err := syntax.Quote(file, syntax.LangAuto)
if err != nil {
return err
}
fmt.Fprintln(hc.Stdout, v)
} }
return nil
} }
func makeRelativePath(basePath, fullPath string) (string, error) { func makeRelativePath(basePath, fullPath string) (string, error) {
@ -92,8 +97,7 @@ func filesFindLangCmd(hc interp.HandlerContext, cmd string, args []string) error
return fmt.Errorf("files-find-lang: %w", err) return fmt.Errorf("files-find-lang: %w", err)
} }
outputFiles(hc, langFiles) return outputFiles(hc, langFiles)
return nil
} }
func filesFindDocCmd(hc interp.HandlerContext, cmd string, args []string) error { func filesFindDocCmd(hc interp.HandlerContext, cmd string, args []string) error {
@ -142,13 +146,12 @@ func filesFindDocCmd(hc interp.HandlerContext, cmd string, args []string) error
} }
} }
outputFiles(hc, docFiles) return outputFiles(hc, docFiles)
return nil
} }
func filesFindCmd(hc interp.HandlerContext, cmd string, args []string) error { func filesFindCmd(hc interp.HandlerContext, cmd string, args []string) error {
if len(args) == 0 { if len(args) == 0 {
return fmt.Errorf("find-files: at least one glob pattern is required") return fmt.Errorf("files-find: at least one glob pattern is required")
} }
var foundFiles []string var foundFiles []string
@ -157,11 +160,10 @@ func filesFindCmd(hc interp.HandlerContext, cmd string, args []string) error {
searchPath := path.Join(hc.Dir, globPattern) searchPath := path.Join(hc.Dir, globPattern)
basepath, pattern := doublestar.SplitPattern(searchPath) basepath, pattern := doublestar.SplitPattern(searchPath)
fsys := os.DirFS(basepath) fsys := NewDirLFS(basepath)
matches, err := doublestar.Glob(fsys, pattern, doublestar.WithNoFollow()) matches, err := doublestar.Glob(fsys, pattern, doublestar.WithNoFollow(), doublestar.WithFailOnPatternNotExist())
if err != nil { if err != nil {
slog.Warn("find-files: invalid glob pattern", "pattern", globPattern, "error", err) return fmt.Errorf("files-find: glob pattern error: %w", err)
continue
} }
for _, match := range matches { for _, match := range matches {
@ -173,6 +175,5 @@ func filesFindCmd(hc interp.HandlerContext, cmd string, args []string) error {
} }
} }
outputFiles(hc, foundFiles) return outputFiles(hc, foundFiles)
return nil
} }

View File

@ -24,6 +24,8 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/bmatcuk/doublestar/v4"
"github.com/google/shlex"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"mvdan.cc/sh/v3/interp" "mvdan.cc/sh/v3/interp"
"mvdan.cc/sh/v3/syntax" "mvdan.cc/sh/v3/syntax"
@ -43,6 +45,7 @@ type testCase struct {
expectedOutput []string expectedOutput []string
symlinksToCreate []symlink symlinksToCreate []symlink
args string args string
expectedError error
} }
func TestFindFilesDoc(t *testing.T) { func TestFindFilesDoc(t *testing.T) {
@ -131,7 +134,8 @@ files-find-doc ` + tc.args
err = runner.Run(context.Background(), script) err = runner.Run(context.Background(), script)
assert.NoError(t, err) assert.NoError(t, err)
contents := strings.Fields(strings.TrimSpace(buf.String())) contents, err := shlex.Split(buf.String())
assert.NoError(t, err)
assert.ElementsMatch(t, tc.expectedOutput, contents) assert.ElementsMatch(t, tc.expectedOutput, contents)
}) })
} }
@ -215,7 +219,8 @@ files-find-lang ` + tc.args
err = runner.Run(context.Background(), script) err = runner.Run(context.Background(), script)
assert.NoError(t, err) assert.NoError(t, err)
contents := strings.Fields(strings.TrimSpace(buf.String())) contents, err := shlex.Split(buf.String())
assert.NoError(t, err)
assert.ElementsMatch(t, tc.expectedOutput, contents) assert.ElementsMatch(t, tc.expectedOutput, contents)
}) })
} }
@ -230,18 +235,25 @@ func TestFindFiles(t *testing.T) {
"usr/share/locale/tr/LC_MESSAGES", "usr/share/locale/tr/LC_MESSAGES",
"opt/app", "opt/app",
"opt/app/internal", "opt/app/internal",
"opt/app/with space",
"usr/bin",
}, },
filesToCreate: []string{ filesToCreate: []string{
"usr/share/locale/ru/LC_MESSAGES/yandex-disk.mo", "usr/share/locale/ru/LC_MESSAGES/yandex-disk.mo",
"usr/share/locale/ru/LC_MESSAGES/yandex-disk-indicator.mo", "usr/share/locale/ru/LC_MESSAGES/yandex-disk-indicator.mo",
"usr/share/locale/tr/LC_MESSAGES/yandex-disk.mo", "usr/share/locale/tr/LC_MESSAGES/yandex-disk.mo",
"opt/app/internal/test", "opt/app/internal/test",
"opt/app/with space/file",
}, },
symlinksToCreate: []symlink{ symlinksToCreate: []symlink{
{ {
linkPath: "/opt/app/etc", linkPath: "/opt/app/etc",
targetPath: "/etc", targetPath: "/etc",
}, },
{
linkPath: "/usr/bin/file",
targetPath: "/not-existing",
},
}, },
expectedOutput: []string{ expectedOutput: []string{
"./usr/share/locale/ru/LC_MESSAGES/yandex-disk.mo", "./usr/share/locale/ru/LC_MESSAGES/yandex-disk.mo",
@ -250,8 +262,17 @@ func TestFindFiles(t *testing.T) {
"./opt/app/etc", "./opt/app/etc",
"./opt/app/internal", "./opt/app/internal",
"./opt/app/internal/test", "./opt/app/internal/test",
"./opt/app/with space",
"./opt/app/with space/file",
"./usr/bin/file",
}, },
args: "\"/usr/share/locale/*/LC_MESSAGES/*.mo\" \"/opt/app/**/*\"", args: "\"/usr/share/locale/*/LC_MESSAGES/*.mo\" \"/opt/app/**/*\" \"/usr/bin/file\"",
expectedError: nil,
},
{
name: "Not existing paths should throw error",
args: "\"/opt/test/not-existing\"",
expectedError: doublestar.ErrPatternNotExist,
}, },
} }
@ -304,9 +325,14 @@ files-find ` + tc.args
assert.NoError(t, err) assert.NoError(t, err)
err = runner.Run(context.Background(), script) err = runner.Run(context.Background(), script)
assert.NoError(t, err) if tc.expectedError != nil {
assert.ErrorAs(t, err, &tc.expectedError)
} else {
assert.NoError(t, err)
}
contents := strings.Fields(strings.TrimSpace(buf.String())) contents, err := shlex.Split(buf.String())
assert.NoError(t, err)
assert.ElementsMatch(t, tc.expectedOutput, contents) assert.ElementsMatch(t, tc.expectedOutput, contents)
}) })
} }

View File

@ -58,6 +58,50 @@ msgstr ""
msgid "Done" msgid "Done"
msgstr "" msgstr ""
#: config.go:36
msgid "Manage config"
msgstr ""
#: config.go:48
msgid "Show config"
msgstr ""
#: config.go:84
msgid "Set config value"
msgstr ""
#: config.go:85
msgid "<key> <value>"
msgstr ""
#: config.go:118 config.go:126
msgid "invalid boolean value for %s: %s"
msgstr ""
#: config.go:141
msgid "use 'repo add/remove' commands to manage repositories"
msgstr ""
#: config.go:143 config.go:221
msgid "unknown config key: %s"
msgstr ""
#: config.go:147
msgid "failed to save config"
msgstr ""
#: config.go:150
msgid "Successfully set %s = %s"
msgstr ""
#: config.go:159
msgid "Get config value"
msgstr ""
#: config.go:160
msgid "<key>"
msgstr ""
#: fix.go:39 #: fix.go:39
msgid "Attempt to fix problems with ALR" msgid "Attempt to fix problems with ALR"
msgstr "" msgstr ""
@ -174,19 +218,23 @@ msgstr ""
msgid "Error removing packages" msgid "Error removing packages"
msgstr "" msgstr ""
#: internal/build/build.go:376 #: internal/build/build.go:378
msgid "Building package" msgid "Building package"
msgstr "" msgstr ""
#: internal/build/build.go:405 #: internal/build/build.go:407
msgid "The checksums array must be the same length as sources" msgid "The checksums array must be the same length as sources"
msgstr "" msgstr ""
#: internal/build/build.go:447 #: internal/build/build.go:449
msgid "Downloading sources" msgid "Downloading sources"
msgstr "" msgstr ""
#: internal/build/build.go:539 #: internal/build/build.go:495
msgid "Would you like to remove the build dependencies?"
msgstr ""
#: internal/build/build.go:571
msgid "Installing dependencies" msgid "Installing dependencies"
msgstr "" msgstr ""
@ -433,11 +481,11 @@ msgstr ""
msgid "Enable interactive questions and prompts" msgid "Enable interactive questions and prompts"
msgstr "" msgstr ""
#: main.go:146 #: main.go:147
msgid "Show help" msgid "Show help"
msgstr "" msgstr ""
#: main.go:150 #: main.go:151
msgid "Error while running app" msgid "Error while running app"
msgstr "" msgstr ""
@ -445,15 +493,15 @@ msgstr ""
msgid "Source can be updated, updating if required" msgid "Source can be updated, updating if required"
msgstr "" msgstr ""
#: pkg/dl/dl.go:201 #: pkg/dl/dl.go:196
msgid "Source found in cache and linked to destination" msgid "Source found in cache and linked to destination"
msgstr "" msgstr ""
#: pkg/dl/dl.go:208 #: pkg/dl/dl.go:203
msgid "Source updated and linked to destination" msgid "Source updated and linked to destination"
msgstr "" msgstr ""
#: pkg/dl/dl.go:222 #: pkg/dl/dl.go:217
msgid "Downloading source" msgid "Downloading source"
msgstr "" msgstr ""

View File

@ -5,7 +5,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: unnamed project\n" "Project-Id-Version: unnamed project\n"
"PO-Revision-Date: 2025-06-19 18:54+0300\n" "PO-Revision-Date: 2025-06-29 21:05+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"
@ -65,6 +65,50 @@ msgstr "Ошибка при перемещении пакета"
msgid "Done" msgid "Done"
msgstr "Сделано" msgstr "Сделано"
#: config.go:36
msgid "Manage config"
msgstr "Управление конфигурацией"
#: config.go:48
msgid "Show config"
msgstr "Показать конфигурацию"
#: config.go:84
msgid "Set config value"
msgstr "Установить значение в конфигурации"
#: config.go:85
msgid "<key> <value>"
msgstr "<ключ> <значение>"
#: config.go:118 config.go:126
msgid "invalid boolean value for %s: %s"
msgstr "неверное булево значение для %s: %s"
#: config.go:141
msgid "use 'repo add/remove' commands to manage repositories"
msgstr "используйте команды 'repo add/remove' для управления репозиториями"
#: config.go:143 config.go:221
msgid "unknown config key: %s"
msgstr "неизвестный ключ конфигурации: %s"
#: config.go:147
msgid "failed to save config"
msgstr "не удалось сохранить конфигурацию"
#: config.go:150
msgid "Successfully set %s = %s"
msgstr "Успешно установлено %s = %s"
#: config.go:159
msgid "Get config value"
msgstr "Получить значение из конфигурации"
#: config.go:160
msgid "<key>"
msgstr "<ключ>"
#: fix.go:39 #: fix.go:39
msgid "Attempt to fix problems with ALR" msgid "Attempt to fix problems with ALR"
msgstr "Попытка устранить проблемы с ALR" msgstr "Попытка устранить проблемы с ALR"
@ -181,19 +225,23 @@ msgstr "Для команды remove ожидался хотя бы 1 аргум
msgid "Error removing packages" msgid "Error removing packages"
msgstr "Ошибка при удалении пакетов" msgstr "Ошибка при удалении пакетов"
#: internal/build/build.go:376 #: internal/build/build.go:378
msgid "Building package" msgid "Building package"
msgstr "Сборка пакета" msgstr "Сборка пакета"
#: internal/build/build.go:405 #: internal/build/build.go:407
msgid "The checksums array must be the same length as sources" msgid "The checksums array must be the same length as sources"
msgstr "Массив контрольных сумм должен быть той же длины, что и источники" msgstr "Массив контрольных сумм должен быть той же длины, что и источники"
#: internal/build/build.go:447 #: internal/build/build.go:449
msgid "Downloading sources" msgid "Downloading sources"
msgstr "Скачивание источников" msgstr "Скачивание источников"
#: internal/build/build.go:539 #: internal/build/build.go:495
msgid "Would you like to remove the build dependencies?"
msgstr "Хотели бы вы удалить зависимости сборки?"
#: internal/build/build.go:571
msgid "Installing dependencies" msgid "Installing dependencies"
msgstr "Установка зависимостей" msgstr "Установка зависимостей"
@ -449,11 +497,11 @@ msgstr "Аргументы, которые будут переданы мене
msgid "Enable interactive questions and prompts" msgid "Enable interactive questions and prompts"
msgstr "Включение интерактивных вопросов и запросов" msgstr "Включение интерактивных вопросов и запросов"
#: main.go:146 #: main.go:147
msgid "Show help" msgid "Show help"
msgstr "Показать справку" msgstr "Показать справку"
#: main.go:150 #: main.go:151
msgid "Error while running app" msgid "Error while running app"
msgstr "Ошибка при запуске приложения" msgstr "Ошибка при запуске приложения"
@ -461,15 +509,15 @@ msgstr "Ошибка при запуске приложения"
msgid "Source can be updated, updating if required" msgid "Source can be updated, updating if required"
msgstr "Исходный код можно обновлять, обновляя при необходимости" msgstr "Исходный код можно обновлять, обновляя при необходимости"
#: pkg/dl/dl.go:201 #: pkg/dl/dl.go:196
msgid "Source found in cache and linked to destination" msgid "Source found in cache and linked to destination"
msgstr "Источник найден в кэше и связан с пунктом назначения" msgstr "Источник найден в кэше и связан с пунктом назначения"
#: pkg/dl/dl.go:208 #: pkg/dl/dl.go:203
msgid "Source updated and linked to destination" msgid "Source updated and linked to destination"
msgstr "Источник обновлён и связан с пунктом назначения" msgstr "Источник обновлён и связан с пунктом назначения"
#: pkg/dl/dl.go:222 #: pkg/dl/dl.go:217
msgid "Downloading source" msgid "Downloading source"
msgstr "Скачивание источника" msgstr "Скачивание источника"
@ -663,9 +711,6 @@ msgstr "Здесь нечего делать."
#~ msgid "Installing build dependencies" #~ msgid "Installing build dependencies"
#~ msgstr "Установка зависимостей сборки" #~ msgstr "Установка зависимостей сборки"
#~ msgid "Would you like to remove the build dependencies?"
#~ msgstr "Хотели бы вы удалить зависимости сборки?"
#~ msgid "Error installing native packages" #~ msgid "Error installing native packages"
#~ msgstr "Ошибка при установке нативных пакетов" #~ msgstr "Ошибка при установке нативных пакетов"
@ -682,9 +727,6 @@ msgstr "Здесь нечего делать."
#~ msgid "Unable to detect user config directory" #~ msgid "Unable to detect user config directory"
#~ msgstr "Не удалось обнаружить каталог конфигурации пользователя" #~ msgstr "Не удалось обнаружить каталог конфигурации пользователя"
#~ msgid "Unable to create ALR config file"
#~ msgstr "Не удалось создать конфигурационный файл ALR"
#~ msgid "Error encoding default configuration" #~ msgid "Error encoding default configuration"
#~ msgstr "Ошибка кодирования конфигурации по умолчанию" #~ msgstr "Ошибка кодирования конфигурации по умолчанию"

View File

@ -83,6 +83,7 @@ func GetApp() *cli.App {
VersionCmd(), VersionCmd(),
SearchCmd(), SearchCmd(),
RepoCmd(), RepoCmd(),
ConfigCmd(),
// Internal commands // Internal commands
InternalBuildCmd(), InternalBuildCmd(),
InternalInstallCmd(), InternalInstallCmd(),

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
//go:generate go run ../../generators/alrsh-package //go:generate bash -c "go run ../../generators/alrsh-package && cd ../.. && make update-license"
package alrsh package alrsh

View File

@ -172,15 +172,10 @@ func Download(ctx context.Context, opts Options) (err error) {
"downloader", d.Name(), "downloader", d.Name(),
) )
updated, err = d.Update(Options{ newOpts := opts
Hash: opts.Hash, newOpts.Destination = cacheDir
HashAlgorithm: opts.HashAlgorithm,
Name: opts.Name, updated, err = d.Update(newOpts)
URL: opts.URL,
Destination: cacheDir,
Progress: opts.Progress,
LocalDir: opts.LocalDir,
})
if err != nil { if err != nil {
return err return err
} }
@ -226,15 +221,10 @@ func Download(ctx context.Context, opts Options) (err error) {
return err return err
} }
t, name, err := d.Download(ctx, Options{ newOpts := opts
Hash: opts.Hash, newOpts.Destination = cacheDir
HashAlgorithm: opts.HashAlgorithm,
Name: opts.Name, t, name, err := d.Download(ctx, newOpts)
URL: opts.URL,
Destination: cacheDir,
Progress: opts.Progress,
LocalDir: opts.LocalDir,
})
if err != nil { if err != nil {
return err return err
} }

View File

@ -155,7 +155,7 @@ func TestDownloadFileWithCache(t *testing.T) {
CacheDisabled: false, CacheDisabled: false,
URL: server.URL + "/file", URL: server.URL + "/file",
Destination: tmpdir, Destination: tmpdir,
DlCache: dlcache.New(cfg), DlCache: dlcache.New(cfg.GetPaths().CacheDir),
} }
outputFile := path.Join(tmpdir, "file") outputFile := path.Join(tmpdir, "file")

View File

@ -108,7 +108,7 @@ func (FileDownloader) Download(ctx context.Context, opts Options) (Type, string,
} }
defer r.Close() defer r.Close()
opts.PostprocDisabled = archive == "false" postprocDisabled := opts.PostprocDisabled || archive == "false"
path := filepath.Join(opts.Destination, name) path := filepath.Join(opts.Destination, name)
fl, err := os.Create(path) fl, err := os.Create(path)
@ -154,7 +154,7 @@ func (FileDownloader) Download(ctx context.Context, opts Options) (Type, string,
} }
// Проверка необходимости постобработки // Проверка необходимости постобработки
if opts.PostprocDisabled { if postprocDisabled {
return TypeFile, name, nil return TypeFile, name, nil
} }

View File

@ -32,19 +32,15 @@ type Config interface {
} }
type DownloadCache struct { type DownloadCache struct {
cfg Config cacheDir string
} }
func New(cfg Config) *DownloadCache { func New(cacheDir string) *DownloadCache {
return &DownloadCache{ return &DownloadCache{cacheDir}
cfg,
}
} }
func (dc *DownloadCache) BasePath(ctx context.Context) string { func (dc *DownloadCache) BasePath(ctx context.Context) string {
return filepath.Join( return filepath.Join(dc.cacheDir, "dl")
dc.cfg.GetPaths().CacheDir, "dl",
)
} }
// New creates a new directory with the given ID in the cache. // New creates a new directory with the given ID in the cache.

View File

@ -64,7 +64,7 @@ func TestNew(t *testing.T) {
cfg := prepare(t) cfg := prepare(t)
defer cleanup(t, cfg) defer cleanup(t, cfg)
dc := dlcache.New(cfg) dc := dlcache.New(cfg.GetPaths().CacheDir)
ctx := context.Background() ctx := context.Background()

View File

@ -21,19 +21,19 @@ package types
// Config represents the ALR configuration file // Config represents the ALR configuration file
type Config struct { type Config struct {
RootCmd string `toml:"rootCmd" env:"ALR_ROOT_CMD"` RootCmd string `json:"rootCmd" koanf:"rootCmd"`
UseRootCmd bool `toml:"useRootCmd"` UseRootCmd bool `json:"useRootCmd" koanf:"useRootCmd"`
PagerStyle string `toml:"pagerStyle" env:"ALR_PAGER_STYLE"` PagerStyle string `json:"pagerStyle" koanf:"pagerStyle"`
IgnorePkgUpdates []string `toml:"ignorePkgUpdates"` IgnorePkgUpdates []string `json:"ignorePkgUpdates" koanf:"ignorePkgUpdates"`
Repos []Repo `toml:"repo"` Repos []Repo `json:"repo" koanf:"repo"`
AutoPull bool `toml:"autoPull" env:"ALR_AUTOPULL"` AutoPull bool `json:"autoPull" koanf:"autoPull"`
LogLevel string `toml:"logLevel" env:"ALR_LOG_LEVEL"` LogLevel string `json:"logLevel" koanf:"logLevel"`
} }
// Repo represents a ALR repo within a configuration file // Repo represents a ALR repo within a configuration file
type Repo struct { type Repo struct {
Name string `toml:"name"` Name string `json:"name" koanf:"name"`
URL string `toml:"url"` URL string `json:"url" koanf:"url"`
Ref string `toml:"ref"` Ref string `json:"ref" koanf:"ref"`
Mirrors []string `toml:"mirrors"` Mirrors []string `json:"mirrors" koanf:"mirrors"`
} }

14
repo.go
View File

@ -108,7 +108,7 @@ func RemoveRepoCmd() *cli.Command {
if err != nil { if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error removing repo directory"), err) return cliutils.FormatCliExit(gotext.Get("Error removing repo directory"), err)
} }
err = cfg.SaveUserConfig() err = cfg.System.Save()
if err != nil { if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error saving config"), err) return cliutils.FormatCliExit(gotext.Get("Error saving config"), err)
} }
@ -175,7 +175,7 @@ func AddRepoCmd() *cli.Command {
}) })
cfg.SetRepos(reposSlice) cfg.SetRepos(reposSlice)
err = cfg.SaveUserConfig() err = cfg.System.Save()
if err != nil { if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error saving config"), err) return cliutils.FormatCliExit(gotext.Get("Error saving config"), err)
} }
@ -248,7 +248,7 @@ func SetRepoRefCmd() *cli.Command {
newRepos = append(newRepos, repo) newRepos = append(newRepos, repo)
} }
deps.Cfg.SetRepos(newRepos) deps.Cfg.SetRepos(newRepos)
err = deps.Cfg.SaveUserConfig() err = deps.Cfg.System.Save()
if err != nil { if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error saving config"), err) return cliutils.FormatCliExit(gotext.Get("Error saving config"), err)
} }
@ -311,7 +311,7 @@ func SetUrlCmd() *cli.Command {
newRepos = append(newRepos, repo) newRepos = append(newRepos, repo)
} }
deps.Cfg.SetRepos(newRepos) deps.Cfg.SetRepos(newRepos)
err = deps.Cfg.SaveUserConfig() err = deps.Cfg.System.Save()
if err != nil { if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error saving config"), err) return cliutils.FormatCliExit(gotext.Get("Error saving config"), err)
} }
@ -384,7 +384,7 @@ func AddMirror() *cli.Command {
} }
} }
deps.Cfg.SetRepos(repos) deps.Cfg.SetRepos(repos)
err = deps.Cfg.SaveUserConfig() err = deps.Cfg.System.Save()
if err != nil { if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error saving config"), err) return cliutils.FormatCliExit(gotext.Get("Error saving config"), err)
} }
@ -499,7 +499,7 @@ func RemoveMirror() *cli.Command {
} }
deps.Cfg.SetRepos(reposSlice) deps.Cfg.SetRepos(reposSlice)
err = deps.Cfg.SaveUserConfig() err = deps.Cfg.System.Save()
if err != nil { if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error saving config"), err) return cliutils.FormatCliExit(gotext.Get("Error saving config"), err)
} }
@ -571,7 +571,7 @@ func ClearMirrors() *cli.Command {
reposSlice[repoIndex].Mirrors = []string{} reposSlice[repoIndex].Mirrors = []string{}
deps.Cfg.SetRepos(reposSlice) deps.Cfg.SetRepos(reposSlice)
err = deps.Cfg.SaveUserConfig() err = deps.Cfg.System.Save()
if err != nil { if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error saving config"), err) return cliutils.FormatCliExit(gotext.Get("Error saving config"), err)
} }