refactor-move-to-pkg #101

Merged
Maks1mS merged 6 commits from Maks1mS/ALR:refactor-move-to-pkg into master 2025-06-12 18:39:43 +00:00
60 changed files with 1197 additions and 1047 deletions

View File

@@ -0,0 +1,69 @@
# 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/>.
name: Update alr-git
on:
push:
branches:
- master
jobs:
changelog:
runs-on: ubuntu-latest
steps:
- name: Install the latest version of uv
uses: astral-sh/setup-uv@v6
- name: Setup alr-spec
run: |
uv tool install alr-spec==0.0.4
- name: Install alr
run: |
apt-get update && apt-get install -y libcap2-bin
curl -fsS https://gitea.plemya-x.ru/Plemya-x/ALR/raw/branch/master/scripts/install.sh | bash
- name: Checkout this repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set ALR version
run: |
echo "NEW_ALR_VERSION=$(alr helper git-version)" >> $GITHUB_ENV
- name: Checkout alr-default repository
uses: actions/checkout@v4
with:
repository: Plemya-x/alr-default
token: ${{ secrets.GITEAPUBLIC }}
path: alr-default
- name: Update version
working-directory: ./alr-default/alr-git
run: |
alr-spec set-filed version $NEW_ALR_VERSION
alr-spec set-filed release 1
- name: Commit changes
run: |
cd alr-default
git config user.name "gitea"
git config user.email "admin@plemya-x.ru"
git add .
git commit -m "Обновление версии до $NEW_ALR_VERSION"
git push

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">16.9%</text> <text x="86" y="15" fill="#010101" fill-opacity=".3">17.6%</text>
<text x="86" y="14">16.9%</text> <text x="86" y="14">17.6%</text>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 926 B

After

Width:  |  Height:  |  Size: 926 B

View File

@@ -32,8 +32,8 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils" "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
appbuilder "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils/app_builder" appbuilder "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils/app_builder"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/osutils" "gitea.plemya-x.ru/Plemya-x/ALR/internal/osutils"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/utils" "gitea.plemya-x.ru/Plemya-x/ALR/internal/utils"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
) )
func BuildCmd() *cli.Command { func BuildCmd() *cli.Command {

View File

@@ -31,8 +31,8 @@ func TestE2EGroupAndSummaryField(t *testing.T) {
RPM_SYSTEMS, RPM_SYSTEMS,
func(t *testing.T, r e2e.Runnable) { func(t *testing.T, r e2e.Runnable) {
defaultPrepare(t, r) defaultPrepare(t, r)
execShouldNoError(t, r, "sh", "-c", "alr search --name test-group-and-summary --format \"{{.Group}}\" | grep ^System/Base$") execShouldNoError(t, r, "sh", "-c", "alr search --name test-group-and-summary --format \"{{.Group.Resolved}}\" | grep ^System/Base$")
execShouldNoError(t, r, "sh", "-c", "alr search --name test-group-and-summary --format \"{{.Summary}}\" | grep \"^Custom summary$\"") execShouldNoError(t, r, "sh", "-c", "alr search --name test-group-and-summary --format \"{{.Summary.Resolved}}\" | grep \"^Custom summary$\"")
}, },
) )
} }

12
go.mod
View File

@@ -8,7 +8,6 @@ require (
gitea.plemya-x.ru/Plemya-x/fakeroot v0.0.2-0.20250408104831-427aaa7713c3 gitea.plemya-x.ru/Plemya-x/fakeroot v0.0.2-0.20250408104831-427aaa7713c3
github.com/AlecAivazis/survey/v2 v2.3.7 github.com/AlecAivazis/survey/v2 v2.3.7
github.com/PuerkitoBio/purell v1.2.0 github.com/PuerkitoBio/purell v1.2.0
github.com/alecthomas/assert/v2 v2.2.1
github.com/alecthomas/chroma/v2 v2.9.1 github.com/alecthomas/chroma/v2 v2.9.1
github.com/caarlos0/env v3.5.0+incompatible github.com/caarlos0/env v3.5.0+incompatible
github.com/charmbracelet/bubbles v0.20.0 github.com/charmbracelet/bubbles v0.20.0
@@ -42,6 +41,7 @@ require (
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
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
xorm.io/xorm v1.3.9
) )
require ( require (
@@ -52,7 +52,6 @@ require (
github.com/Masterminds/sprig/v3 v3.2.3 // indirect github.com/Masterminds/sprig/v3 v3.2.3 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/ProtonMail/go-crypto v1.1.3 // indirect github.com/ProtonMail/go-crypto v1.1.3 // indirect
github.com/alecthomas/repr v0.2.0 // indirect
github.com/andybalholm/brotli v1.0.4 // indirect github.com/andybalholm/brotli v1.0.4 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb // indirect github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb // indirect
@@ -79,6 +78,7 @@ require (
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/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/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect github.com/golang/snappy v0.0.4 // indirect
@@ -90,10 +90,10 @@ require (
github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect github.com/hashicorp/yamux v0.1.1 // indirect
github.com/hexops/gotextdiff v1.0.3 // indirect
github.com/huandu/xstrings v1.3.3 // indirect github.com/huandu/xstrings v1.3.3 // indirect
github.com/imdario/mergo v0.3.16 // indirect github.com/imdario/mergo v0.3.16 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
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
@@ -105,6 +105,8 @@ require (
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/termenv v0.15.2 // indirect github.com/muesli/termenv v0.15.2 // indirect
@@ -117,9 +119,10 @@ require (
github.com/rivo/uniseg v0.4.7 // indirect github.com/rivo/uniseg v0.4.7 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
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.2.0 // 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.6.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
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
@@ -145,4 +148,5 @@ require (
modernc.org/opt v0.1.3 // indirect modernc.org/opt v0.1.3 // indirect
modernc.org/strutil v1.1.3 // indirect modernc.org/strutil v1.1.3 // indirect
modernc.org/token v1.0.1 // indirect modernc.org/token v1.0.1 // indirect
xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978 // indirect
) )

43
go.sum
View File

@@ -17,6 +17,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
gitea.plemya-x.ru/Plemya-x/fakeroot v0.0.2-0.20250408104831-427aaa7713c3 h1:56BjRJJ2Sv50DfSvNUydUMJwwFuiBMWC1uYtH2GYjk8= gitea.plemya-x.ru/Plemya-x/fakeroot v0.0.2-0.20250408104831-427aaa7713c3 h1:56BjRJJ2Sv50DfSvNUydUMJwwFuiBMWC1uYtH2GYjk8=
gitea.plemya-x.ru/Plemya-x/fakeroot v0.0.2-0.20250408104831-427aaa7713c3/go.mod h1:iKQM6uttMJgE5CFrPw6SQqAV7TKtlJNICRAie/dTciw= gitea.plemya-x.ru/Plemya-x/fakeroot v0.0.2-0.20250408104831-427aaa7713c3/go.mod h1:iKQM6uttMJgE5CFrPw6SQqAV7TKtlJNICRAie/dTciw=
github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ= github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ=
@@ -137,6 +139,7 @@ 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/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/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=
@@ -153,10 +156,13 @@ github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI= github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=
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.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
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/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/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -176,6 +182,7 @@ github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaW
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@@ -187,6 +194,7 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/goterm v0.0.0-20190703233501-fc88cf888a3f h1:5CjVwnuUcp5adK4gmY6i72gpVFVnZDP2h5TmPScB6u4= github.com/google/goterm v0.0.0-20190703233501-fc88cf888a3f h1:5CjVwnuUcp5adK4gmY6i72gpVFVnZDP2h5TmPScB6u4=
github.com/google/goterm v0.0.0-20190703233501-fc88cf888a3f/go.mod h1:nOFQdrUlIlx6M6ODdSpBj1NVA+VgLC6kmw60mkw34H4= github.com/google/goterm v0.0.0-20190703233501-fc88cf888a3f/go.mod h1:nOFQdrUlIlx6M6ODdSpBj1NVA+VgLC6kmw60mkw34H4=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
@@ -229,6 +237,8 @@ github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUq
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog= github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4= github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4=
github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
@@ -245,6 +255,8 @@ github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
@@ -269,8 +281,9 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leonelquinteros/gotext v1.7.0 h1:jcJmF4AXqyamP7vuw2MMIKs+O3jAEmvrc5JQiI8Ht/8= github.com/leonelquinteros/gotext v1.7.0 h1:jcJmF4AXqyamP7vuw2MMIKs+O3jAEmvrc5JQiI8Ht/8=
github.com/leonelquinteros/gotext v1.7.0/go.mod h1:qJdoQuERPpccw7L70uoU+K/BvTfRBHYsisCQyFLXyvw= github.com/leonelquinteros/gotext v1.7.0/go.mod h1:qJdoQuERPpccw7L70uoU+K/BvTfRBHYsisCQyFLXyvw=
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
@@ -306,6 +319,11 @@ github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
@@ -320,6 +338,10 @@ github.com/nwaples/rardecode/v2 v2.0.0-beta.2 h1:e3mzJFJs4k83GXBEiTaQ5HgSc/kOK8q
github.com/nwaples/rardecode/v2 v2.0.0-beta.2/go.mod h1:yntwv/HfMc/Hbvtq9I19D1n58te3h6KsqCf3GxyfBGY= github.com/nwaples/rardecode/v2 v2.0.0-beta.2/go.mod h1:yntwv/HfMc/Hbvtq9I19D1n58te3h6KsqCf3GxyfBGY=
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
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.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
@@ -358,8 +380,9 @@ github.com/sassoftware/go-rpmutils v0.4.0 h1:ojND82NYBxgwrV+mX1CWsd5QJvvEZTKddtC
github.com/sassoftware/go-rpmutils v0.4.0/go.mod h1:3goNWi7PGAT3/dlql2lv3+MSN5jNYPjT5mVcQcIsYzI= github.com/sassoftware/go-rpmutils v0.4.0/go.mod h1:3goNWi7PGAT3/dlql2lv3+MSN5jNYPjT5mVcQcIsYzI=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY=
github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M=
@@ -374,6 +397,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 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/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.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=
@@ -382,6 +406,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 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/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/tailscale/goexpect v0.0.0-20210902213824-6e8c725cea41 h1:/V2rCMMWcsjYaYO2MeovLw+ClP63OtXgCF2Y1eb8+Ns= github.com/tailscale/goexpect v0.0.0-20210902213824-6e8c725cea41 h1:/V2rCMMWcsjYaYO2MeovLw+ClP63OtXgCF2Y1eb8+Ns=
github.com/tailscale/goexpect v0.0.0-20210902213824-6e8c725cea41/go.mod h1:/roCdA6gg6lQyw/Oz6gIIGu3ggJKYhF+WC/AQReE5XQ= github.com/tailscale/goexpect v0.0.0-20210902213824-6e8c725cea41/go.mod h1:/roCdA6gg6lQyw/Oz6gIIGu3ggJKYhF+WC/AQReE5XQ=
github.com/therootcompany/xz v1.0.1 h1:CmOtsn1CbtmyYiusbfmhmkpAAETj0wBIH6kCYaX+xzw= github.com/therootcompany/xz v1.0.1 h1:CmOtsn1CbtmyYiusbfmhmkpAAETj0wBIH6kCYaX+xzw=
@@ -453,6 +479,7 @@ golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -488,6 +515,7 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -612,8 +640,13 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
@@ -659,3 +692,7 @@ mvdan.cc/sh/v3 v3.10.0/go.mod h1:z/mSSVyLFGZzqb3ZIKojjyqIx/xbmz/UHdCSv9HmqXY=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978 h1:bvLlAPW1ZMTWA32LuZMBEGHAUOcATZjzHcotf3SWweM=
xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
xorm.io/xorm v1.3.9 h1:TUovzS0ko+IQ1XnNLfs5dqK1cJl1H5uHpWbWqAQ04nU=
xorm.io/xorm v1.3.9/go.mod h1:LsCCffeeYp63ssk0pKumP6l96WZcHix7ChpurcLNuMw=

View File

@@ -32,8 +32,8 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils" "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cpu" "gitea.plemya-x.ru/Plemya-x/ALR/internal/cpu"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/helpers" "gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/helpers"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
) )
func HelperCmd() *cli.Command { func HelperCmd() *cli.Command {

17
info.go
View File

@@ -30,10 +30,10 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils" "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
appbuilder "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils/app_builder" appbuilder "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils/app_builder"
database "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/overrides" "gitea.plemya-x.ru/Plemya-x/ALR/internal/overrides"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/utils" "gitea.plemya-x.ru/Plemya-x/ALR/internal/utils"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
) )
func InfoCmd() *cli.Command { func InfoCmd() *cli.Command {
@@ -67,15 +67,8 @@ func InfoCmd() *cli.Command {
if err != nil { if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error getting packages"), err) return cliutils.FormatCliExit(gotext.Get("Error getting packages"), err)
} }
defer result.Close()
for result.Next() {
var pkg database.Package
err = result.StructScan(&pkg)
if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error iterating over packages"), err)
}
for _, pkg := range result {
fmt.Println(pkg.Name) fmt.Println(pkg.Name)
} }
return nil return nil
@@ -96,6 +89,7 @@ func InfoCmd() *cli.Command {
New(ctx). New(ctx).
WithConfig(). WithConfig().
WithDB(). WithDB().
WithDistroInfo().
WithRepos(). WithRepos().
Build() Build()
if err != nil { if err != nil {
@@ -144,7 +138,8 @@ func InfoCmd() *cli.Command {
for _, pkg := range pkgs { for _, pkg := range pkgs {
if !all { if !all {
err = yaml.NewEncoder(os.Stdout).Encode(overrides.ResolvePackage(&pkg, names)) alrsh.ResolvePackage(&pkg, names)
err = yaml.NewEncoder(os.Stdout).Encode(pkg)
if err != nil { if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error encoding script variables"), err) return cliutils.FormatCliExit(gotext.Get("Error encoding script variables"), err)
} }

View File

@@ -28,10 +28,9 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/build" "gitea.plemya-x.ru/Plemya-x/ALR/internal/build"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils" "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
appbuilder "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils/app_builder" appbuilder "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils/app_builder"
database "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/manager" "gitea.plemya-x.ru/Plemya-x/ALR/internal/manager"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/utils" "gitea.plemya-x.ru/Plemya-x/ALR/internal/utils"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
) )
func InstallCmd() *cli.Command { func InstallCmd() *cli.Command {
@@ -136,15 +135,8 @@ func InstallCmd() *cli.Command {
if err != nil { if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error getting packages"), err) return cliutils.FormatCliExit(gotext.Get("Error getting packages"), err)
} }
defer result.Close()
for result.Next() {
var pkg database.Package
err = result.StructScan(&pkg)
if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error iterating over packages"), err)
}
for _, pkg := range result {
fmt.Println(pkg.Name) fmt.Println(pkg.Name)
} }
@@ -190,20 +182,12 @@ func RemoveCmd() *cli.Command {
if err != nil { if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error getting packages"), err) return cliutils.FormatCliExit(gotext.Get("Error getting packages"), err)
} }
defer result.Close()
for result.Next() {
var pkg database.Package
err = result.StructScan(&pkg)
if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error iterating over packages"), err)
}
for _, pkg := range result {
_, ok := installedAlrPackages[fmt.Sprintf("%s/%s", pkg.Repository, pkg.Name)] _, ok := installedAlrPackages[fmt.Sprintf("%s/%s", pkg.Repository, pkg.Name)]
if !ok { if !ok {
continue continue
} }
fmt.Println(pkg.Name) fmt.Println(pkg.Name)
} }

View File

@@ -24,18 +24,17 @@ import (
"context" "context"
"encoding/gob" "encoding/gob"
"errors" "errors"
"fmt"
"log/slog" "log/slog"
"github.com/leonelquinteros/gotext" "github.com/leonelquinteros/gotext"
"mvdan.cc/sh/v3/syntax"
"mvdan.cc/sh/v3/syntax/typedjson"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils" "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config" "gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/manager" "gitea.plemya-x.ru/Plemya-x/ALR/internal/manager"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
) )
type BuildInput struct { type BuildInput struct {
@@ -133,47 +132,6 @@ type RepositoryProvider interface {
// ================================================ // ================================================
type ScriptFile struct {
File *syntax.File
Path string
}
func (s *ScriptFile) GobEncode() ([]byte, error) {
var buf bytes.Buffer
enc := gob.NewEncoder(&buf)
if err := enc.Encode(s.Path); err != nil {
return nil, err
}
var fileBuf bytes.Buffer
if err := typedjson.Encode(&fileBuf, s.File); err != nil {
return nil, err
}
fileData := fileBuf.Bytes()
if err := enc.Encode(fileData); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func (s *ScriptFile) GobDecode(data []byte) error {
buf := bytes.NewBuffer(data)
dec := gob.NewDecoder(buf)
if err := dec.Decode(&s.Path); err != nil {
return err
}
var fileData []byte
if err := dec.Decode(&fileData); err != nil {
return err
}
fileReader := bytes.NewReader(fileData)
file, err := typedjson.Decode(fileReader)
if err != nil {
return err
}
s.File = file.(*syntax.File)
return nil
}
type BuiltDep struct { type BuiltDep struct {
Name string Name string
Path string Path string
@@ -200,7 +158,7 @@ func GetBuiltName(deps []*BuiltDep) []string {
} }
type PackageFinder interface { type PackageFinder interface {
FindPkgs(ctx context.Context, pkgs []string) (map[string][]db.Package, []string, error) FindPkgs(ctx context.Context, pkgs []string) (map[string][]alrsh.Package, []string, error)
} }
type Config interface { type Config interface {
@@ -215,12 +173,12 @@ type FunctionsOutput struct {
// EXECUTORS // EXECUTORS
type ScriptResolverExecutor interface { type ScriptResolverExecutor interface {
ResolveScript(ctx context.Context, pkg *db.Package) *ScriptInfo ResolveScript(ctx context.Context, pkg *alrsh.Package) *ScriptInfo
} }
type ScriptExecutor interface { type ScriptExecutor interface {
ReadScript(ctx context.Context, scriptPath string) (*ScriptFile, error) ReadScript(ctx context.Context, scriptPath string) (*alrsh.ScriptFile, error)
ExecuteFirstPass(ctx context.Context, input *BuildInput, sf *ScriptFile) (string, []*types.BuildVars, error) ExecuteFirstPass(ctx context.Context, input *BuildInput, sf *alrsh.ScriptFile) (string, []*alrsh.Package, error)
PrepareDirs( PrepareDirs(
ctx context.Context, ctx context.Context,
input *BuildInput, input *BuildInput,
@@ -229,8 +187,8 @@ type ScriptExecutor interface {
ExecuteSecondPass( ExecuteSecondPass(
ctx context.Context, ctx context.Context,
input *BuildInput, input *BuildInput,
sf *ScriptFile, sf *alrsh.ScriptFile,
varsOfPackages []*types.BuildVars, varsOfPackages []*alrsh.Package,
repoDeps []string, repoDeps []string,
builtDeps []*BuiltDep, builtDeps []*BuiltDep,
basePkg string, basePkg string,
@@ -238,18 +196,18 @@ type ScriptExecutor interface {
} }
type CacheExecutor interface { type CacheExecutor interface {
CheckForBuiltPackage(ctx context.Context, input *BuildInput, vars *types.BuildVars) (string, bool, error) CheckForBuiltPackage(ctx context.Context, input *BuildInput, vars *alrsh.Package) (string, bool, error)
} }
type ScriptViewerExecutor interface { type ScriptViewerExecutor interface {
ViewScript(ctx context.Context, input *BuildInput, sf *ScriptFile, basePkg string) error ViewScript(ctx context.Context, input *BuildInput, sf *alrsh.ScriptFile, basePkg string) error
} }
type CheckerExecutor interface { type CheckerExecutor interface {
PerformChecks( PerformChecks(
ctx context.Context, ctx context.Context,
input *BuildInput, input *BuildInput,
vars *types.BuildVars, vars *alrsh.Package,
) (bool, error) ) (bool, error)
} }
@@ -327,7 +285,7 @@ func (b *BuildArgs) PkgFormat() string {
type BuildPackageFromDbArgs struct { type BuildPackageFromDbArgs struct {
BuildArgs BuildArgs
Package *db.Package Package *alrsh.Package
Packages []string Packages []string
} }
@@ -376,19 +334,19 @@ func (b *Builder) BuildPackage(
slog.Debug("ReadScript") slog.Debug("ReadScript")
sf, err := b.scriptExecutor.ReadScript(ctx, scriptPath) sf, err := b.scriptExecutor.ReadScript(ctx, scriptPath)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("failed reading script: %w", err)
} }
slog.Debug("ExecuteFirstPass") slog.Debug("ExecuteFirstPass")
basePkg, varsOfPackages, err := b.scriptExecutor.ExecuteFirstPass(ctx, input, sf) basePkg, varsOfPackages, err := b.scriptExecutor.ExecuteFirstPass(ctx, input, sf)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("failed ExecuteFirstPass: %w", err)
} }
var builtDeps []*BuiltDep var builtDeps []*BuiltDep
if !input.opts.Clean { if !input.opts.Clean {
var remainingVars []*types.BuildVars var remainingVars []*alrsh.Package
for _, vars := range varsOfPackages { for _, vars := range varsOfPackages {
builtPkgPath, ok, err := b.cacheExecutor.CheckForBuiltPackage(ctx, input, vars) builtPkgPath, ok, err := b.cacheExecutor.CheckForBuiltPackage(ctx, input, vars)
if err != nil { if err != nil {
@@ -409,6 +367,7 @@ func (b *Builder) BuildPackage(
} }
slog.Debug("ViewScript") slog.Debug("ViewScript")
slog.Debug("", "varsOfPackages", varsOfPackages)
err = b.scriptViewerExecutor.ViewScript(ctx, input, sf, basePkg) err = b.scriptViewerExecutor.ViewScript(ctx, input, sf, basePkg)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -432,11 +391,11 @@ func (b *Builder) BuildPackage(
sources := []string{} sources := []string{}
checksums := []string{} checksums := []string{}
for _, vars := range varsOfPackages { for _, vars := range varsOfPackages {
buildDepends = append(buildDepends, vars.BuildDepends...) buildDepends = append(buildDepends, vars.BuildDepends.Resolved()...)
optDepends = append(optDepends, vars.OptDepends...) optDepends = append(optDepends, vars.OptDepends.Resolved()...)
depends = append(depends, vars.Depends...) depends = append(depends, vars.Depends.Resolved()...)
sources = append(sources, vars.Sources...) sources = append(sources, vars.Sources.Resolved()...)
checksums = append(checksums, vars.Checksums...) checksums = append(checksums, vars.Checksums.Resolved()...)
} }
buildDepends = removeDuplicates(buildDepends) buildDepends = removeDuplicates(buildDepends)
optDepends = removeDuplicates(optDepends) optDepends = removeDuplicates(optDepends)
@@ -523,7 +482,7 @@ func (b *Builder) BuildPackage(
type InstallPkgsArgs struct { type InstallPkgsArgs struct {
BuildArgs BuildArgs
AlrPkgs []db.Package AlrPkgs []alrsh.Package
NativePkgs []string NativePkgs []string
} }
@@ -534,7 +493,7 @@ func (b *Builder) InstallALRPackages(
BuildOptsProvider BuildOptsProvider
PkgFormatProvider PkgFormatProvider
}, },
alrPkgs []db.Package, alrPkgs []alrsh.Package,
) error { ) error {
for _, pkg := range alrPkgs { for _, pkg := range alrPkgs {
res, err := b.BuildPackageFromDb( res, err := b.BuildPackageFromDb(
@@ -581,7 +540,7 @@ func (b *Builder) BuildALRDeps(
found, notFound, err := b.repos.FindPkgs(ctx, depends) // Поиск зависимостей found, notFound, err := b.repos.FindPkgs(ctx, depends) // Поиск зависимостей
if err != nil { if err != nil {
return nil, nil, err return nil, nil, fmt.Errorf("failed FindPkgs: %w", err)
} }
repoDeps = notFound repoDeps = notFound
@@ -593,7 +552,7 @@ func (b *Builder) BuildALRDeps(
input.BuildOpts().Interactive, input.BuildOpts().Interactive,
) )
type item struct { type item struct {
pkg *db.Package pkg *alrsh.Package
packages []string packages []string
} }
pkgsMap := make(map[string]*item) pkgsMap := make(map[string]*item)
@@ -628,7 +587,7 @@ func (b *Builder) BuildALRDeps(
}, },
) )
if err != nil { if err != nil {
return nil, nil, err return nil, nil, fmt.Errorf("failed build package from db: %w", err)
} }
buildDeps = append(buildDeps, res...) buildDeps = append(buildDeps, res...)

View File

@@ -28,8 +28,8 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config" "gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/db" "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/distro" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/manager" "gitea.plemya-x.ru/Plemya-x/ALR/internal/manager"
) )

View File

@@ -23,7 +23,7 @@ import (
"github.com/goreleaser/nfpm/v2" "github.com/goreleaser/nfpm/v2"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
) )
type Cache struct { type Cache struct {
@@ -33,7 +33,7 @@ type Cache struct {
func (c *Cache) CheckForBuiltPackage( func (c *Cache) CheckForBuiltPackage(
ctx context.Context, ctx context.Context,
input *BuildInput, input *BuildInput,
vars *types.BuildVars, vars *alrsh.Package,
) (string, bool, error) { ) (string, bool, error) {
filename, err := pkgFileName(input, vars) filename, err := pkgFileName(input, vars)
if err != nil { if err != nil {
@@ -56,7 +56,7 @@ func pkgFileName(
PkgFormatProvider PkgFormatProvider
RepositoryProvider RepositoryProvider
}, },
vars *types.BuildVars, vars *alrsh.Package,
) (string, error) { ) (string, error) {
pkgInfo := getBasePkgInfo(vars, input) pkgInfo := getBasePkgInfo(vars, input)

View File

@@ -25,7 +25,7 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils" "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cpu" "gitea.plemya-x.ru/Plemya-x/ALR/internal/cpu"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/manager" "gitea.plemya-x.ru/Plemya-x/ALR/internal/manager"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
) )
type Checker struct { type Checker struct {
@@ -35,7 +35,7 @@ type Checker struct {
func (c *Checker) PerformChecks( func (c *Checker) PerformChecks(
ctx context.Context, ctx context.Context,
input *BuildInput, input *BuildInput,
vars *types.BuildVars, vars *alrsh.Package,
) (bool, error) { ) (bool, error) {
if !cpu.IsCompatibleWith(cpu.Arch(), vars.Architectures) { // Проверяем совместимость архитектуры if !cpu.IsCompatibleWith(cpu.Arch(), vars.Architectures) { // Проверяем совместимость архитектуры
cont, err := cliutils.YesNoPrompt( cont, err := cliutils.YesNoPrompt(

View File

@@ -19,7 +19,7 @@ package build
import ( import (
"path/filepath" "path/filepath"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
) )
type BaseDirProvider interface { type BaseDirProvider interface {

View File

@@ -27,7 +27,7 @@ import (
"github.com/goreleaser/nfpm/v2" "github.com/goreleaser/nfpm/v2"
"github.com/leonelquinteros/gotext" "github.com/leonelquinteros/gotext"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
) )
func rpmFindDependenciesALTLinux(ctx context.Context, pkgInfo *nfpm.Info, dirs types.Directories, command string, envs []string, updateFunc func(string)) error { func rpmFindDependenciesALTLinux(ctx context.Context, pkgInfo *nfpm.Info, dirs types.Directories, command string, envs []string, updateFunc func(string)) error {

View File

@@ -23,7 +23,7 @@ import (
"github.com/goreleaser/nfpm/v2" "github.com/goreleaser/nfpm/v2"
"github.com/leonelquinteros/gotext" "github.com/leonelquinteros/gotext"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
) )
type EmptyFindProvReq struct{} type EmptyFindProvReq struct{}

View File

@@ -28,7 +28,7 @@ import (
"github.com/goreleaser/nfpm/v2" "github.com/goreleaser/nfpm/v2"
"github.com/leonelquinteros/gotext" "github.com/leonelquinteros/gotext"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
) )
type FedoraFindProvReq struct{} type FedoraFindProvReq struct{}

View File

@@ -21,8 +21,8 @@ import (
"github.com/goreleaser/nfpm/v2" "github.com/goreleaser/nfpm/v2"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/distro" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
) )
type ProvReqFinder interface { type ProvReqFinder interface {

View File

@@ -28,7 +28,7 @@ import (
"github.com/hashicorp/go-plugin" "github.com/hashicorp/go-plugin"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/logger" "gitea.plemya-x.ru/Plemya-x/ALR/internal/logger"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
) )
var HandshakeConfig = plugin.HandshakeConfig{ var HandshakeConfig = plugin.HandshakeConfig{
@@ -50,13 +50,13 @@ type ScriptExecutorRPCServer struct {
// ReadScript // ReadScript
// //
func (s *ScriptExecutorRPC) ReadScript(ctx context.Context, scriptPath string) (*ScriptFile, error) { func (s *ScriptExecutorRPC) ReadScript(ctx context.Context, scriptPath string) (*alrsh.ScriptFile, error) {
var resp *ScriptFile var resp *alrsh.ScriptFile
err := s.client.Call("Plugin.ReadScript", scriptPath, &resp) err := s.client.Call("Plugin.ReadScript", scriptPath, &resp)
return resp, err return resp, err
} }
func (s *ScriptExecutorRPCServer) ReadScript(scriptPath string, resp *ScriptFile) error { func (s *ScriptExecutorRPCServer) ReadScript(scriptPath string, resp *alrsh.ScriptFile) error {
file, err := s.Impl.ReadScript(context.Background(), scriptPath) file, err := s.Impl.ReadScript(context.Background(), scriptPath)
if err != nil { if err != nil {
return err return err
@@ -72,15 +72,15 @@ func (s *ScriptExecutorRPCServer) ReadScript(scriptPath string, resp *ScriptFile
type ExecuteFirstPassArgs struct { type ExecuteFirstPassArgs struct {
Input *BuildInput Input *BuildInput
Sf *ScriptFile Sf *alrsh.ScriptFile
} }
type ExecuteFirstPassResp struct { type ExecuteFirstPassResp struct {
BasePkg string BasePkg string
VarsOfPackages []*types.BuildVars VarsOfPackages []*alrsh.Package
} }
func (s *ScriptExecutorRPC) ExecuteFirstPass(ctx context.Context, input *BuildInput, sf *ScriptFile) (string, []*types.BuildVars, error) { func (s *ScriptExecutorRPC) ExecuteFirstPass(ctx context.Context, input *BuildInput, sf *alrsh.ScriptFile) (string, []*alrsh.Package, error) {
var resp *ExecuteFirstPassResp var resp *ExecuteFirstPassResp
err := s.client.Call("Plugin.ExecuteFirstPass", &ExecuteFirstPassArgs{ err := s.client.Call("Plugin.ExecuteFirstPass", &ExecuteFirstPassArgs{
Input: input, Input: input,
@@ -148,8 +148,8 @@ func (s *ScriptExecutorRPCServer) PrepareDirs(args *PrepareDirsArgs, reply *stru
type ExecuteSecondPassArgs struct { type ExecuteSecondPassArgs struct {
Input *BuildInput Input *BuildInput
Sf *ScriptFile Sf *alrsh.ScriptFile
VarsOfPackages []*types.BuildVars VarsOfPackages []*alrsh.Package
RepoDeps []string RepoDeps []string
BuiltDeps []*BuiltDep BuiltDeps []*BuiltDep
BasePkg string BasePkg string
@@ -158,8 +158,8 @@ type ExecuteSecondPassArgs struct {
func (s *ScriptExecutorRPC) ExecuteSecondPass( func (s *ScriptExecutorRPC) ExecuteSecondPass(
ctx context.Context, ctx context.Context,
input *BuildInput, input *BuildInput,
sf *ScriptFile, sf *alrsh.ScriptFile,
varsOfPackages []*types.BuildVars, varsOfPackages []*alrsh.Package,
repoDeps []string, repoDeps []string,
builtDeps []*BuiltDep, builtDeps []*BuiltDep,
basePkg string, basePkg string,

View File

@@ -19,7 +19,6 @@ package build
import ( import (
"bytes" "bytes"
"context" "context"
"errors"
"fmt" "fmt"
"log/slog" "log/slog"
"os" "os"
@@ -37,11 +36,11 @@ import (
"mvdan.cc/sh/v3/syntax" "mvdan.cc/sh/v3/syntax"
finddeps "gitea.plemya-x.ru/Plemya-x/ALR/internal/build/find_deps" finddeps "gitea.plemya-x.ru/Plemya-x/ALR/internal/build/find_deps"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/decoder" "gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/decoder"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/handlers" "gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/handlers"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/helpers" "gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/helpers"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
) )
type LocalScriptExecutor struct { type LocalScriptExecutor struct {
@@ -54,102 +53,12 @@ func NewLocalScriptExecutor(cfg Config) *LocalScriptExecutor {
} }
} }
func (e *LocalScriptExecutor) ReadScript(ctx context.Context, scriptPath string) (*ScriptFile, error) { func (e *LocalScriptExecutor) ReadScript(ctx context.Context, scriptPath string) (*alrsh.ScriptFile, error) {
fl, err := readScript(scriptPath) return alrsh.ReadFromLocal(scriptPath)
if err != nil {
return nil, err
}
return &ScriptFile{
Path: scriptPath,
File: fl,
}, nil
} }
func (e *LocalScriptExecutor) ExecuteFirstPass(ctx context.Context, input *BuildInput, sf *ScriptFile) (string, []*types.BuildVars, error) { func (e *LocalScriptExecutor) ExecuteFirstPass(ctx context.Context, input *BuildInput, sf *alrsh.ScriptFile) (string, []*alrsh.Package, error) {
varsOfPackages := []*types.BuildVars{} return sf.ParseBuildVars(ctx, input.info, input.packages)
scriptDir := filepath.Dir(sf.Path)
env := createBuildEnvVars(input.info, types.Directories{ScriptDir: scriptDir})
runner, err := interp.New(
interp.Env(expand.ListEnviron(env...)), // Устанавливаем окружение
interp.StdIO(os.Stdin, os.Stderr, os.Stderr), // Устанавливаем стандартный ввод-вывод
interp.ExecHandler(helpers.Restricted.ExecHandler(handlers.NopExec)), // Ограничиваем выполнение
interp.ReadDirHandler2(handlers.RestrictedReadDir(scriptDir)), // Ограничиваем чтение директорий
interp.StatHandler(handlers.RestrictedStat(scriptDir)), // Ограничиваем доступ к статистике файлов
interp.OpenHandler(handlers.RestrictedOpen(scriptDir)), // Ограничиваем открытие файлов
interp.Dir(scriptDir),
)
if err != nil {
return "", nil, err
}
err = runner.Run(ctx, sf.File) // Запускаем скрипт
if err != nil {
return "", nil, err
}
dec := decoder.New(input.info, runner) // Создаём новый декодер
type packages struct {
BasePkgName string `sh:"basepkg_name"`
Names []string `sh:"name"`
}
var pkgs packages
err = dec.DecodeVars(&pkgs)
if err != nil {
return "", nil, err
}
if len(pkgs.Names) == 0 {
return "", nil, errors.New("package name is missing")
}
var vars types.BuildVars
if len(pkgs.Names) == 1 {
err = dec.DecodeVars(&vars) // Декодируем переменные
if err != nil {
return "", nil, err
}
varsOfPackages = append(varsOfPackages, &vars)
return vars.Name, varsOfPackages, nil
}
var pkgNames []string
if len(input.packages) != 0 {
pkgNames = input.packages
} else {
pkgNames = pkgs.Names
}
for _, pkgName := range pkgNames {
var preVars types.BuildVarsPre
funcName := fmt.Sprintf("meta_%s", pkgName)
meta, ok := dec.GetFuncWithSubshell(funcName)
if !ok {
return "", nil, fmt.Errorf("func %s is missing", funcName)
}
r, err := meta(ctx)
if err != nil {
return "", nil, err
}
d := decoder.New(&distro.OSRelease{}, r)
err = d.DecodeVars(&preVars)
if err != nil {
return "", nil, err
}
vars := preVars.ToBuildVars()
vars.Name = pkgName
vars.Base = pkgs.BasePkgName
varsOfPackages = append(varsOfPackages, &vars)
}
return pkgs.BasePkgName, varsOfPackages, nil
} }
func (e *LocalScriptExecutor) PrepareDirs( func (e *LocalScriptExecutor) PrepareDirs(
@@ -177,13 +86,13 @@ func (e *LocalScriptExecutor) PrepareDirs(
func (e *LocalScriptExecutor) ExecuteSecondPass( func (e *LocalScriptExecutor) ExecuteSecondPass(
ctx context.Context, ctx context.Context,
input *BuildInput, input *BuildInput,
sf *ScriptFile, sf *alrsh.ScriptFile,
varsOfPackages []*types.BuildVars, varsOfPackages []*alrsh.Package,
repoDeps []string, repoDeps []string,
builtDeps []*BuiltDep, builtDeps []*BuiltDep,
basePkg string, basePkg string,
) ([]*BuiltDep, error) { ) ([]*BuiltDep, error) {
dirs, err := getDirs(e.cfg, sf.Path, basePkg) dirs, err := getDirs(e.cfg, sf.Path(), basePkg)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -201,7 +110,7 @@ func (e *LocalScriptExecutor) ExecuteSecondPass(
return nil, err return nil, err
} }
err = runner.Run(ctx, sf.File) err = runner.Run(ctx, sf.File())
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -217,7 +126,7 @@ func (e *LocalScriptExecutor) ExecuteSecondPass(
for _, vars := range varsOfPackages { for _, vars := range varsOfPackages {
packageName := "" packageName := ""
if vars.Base != "" { if vars.BasePkgName != "" {
packageName = vars.Name packageName = vars.Name
} }
@@ -285,24 +194,25 @@ func buildPkgMetadata(
PkgFormatProvider PkgFormatProvider
RepositoryProvider RepositoryProvider
}, },
vars *types.BuildVars, vars *alrsh.Package,
dirs types.Directories, dirs types.Directories,
deps []string, deps []string,
preferedContents *[]string, preferedContents *[]string,
) (*nfpm.Info, error) { ) (*nfpm.Info, error) {
pkgInfo := getBasePkgInfo(vars, input) pkgInfo := getBasePkgInfo(vars, input)
pkgInfo.Description = vars.Description slog.Warn("vars.Description", "vars.Description", vars.Description, "vars.Description.Resolved", vars.Description.Resolved())
pkgInfo.Description = vars.Description.Resolved()
pkgInfo.Platform = "linux" pkgInfo.Platform = "linux"
pkgInfo.Homepage = vars.Homepage pkgInfo.Homepage = vars.Homepage.Resolved()
pkgInfo.License = strings.Join(vars.Licenses, ", ") pkgInfo.License = strings.Join(vars.Licenses, ", ")
pkgInfo.Maintainer = vars.Maintainer pkgInfo.Maintainer = vars.Maintainer.Resolved()
pkgInfo.Overridables = nfpm.Overridables{ pkgInfo.Overridables = nfpm.Overridables{
Conflicts: append(vars.Conflicts, vars.Name), Conflicts: append(vars.Conflicts, vars.Name),
Replaces: vars.Replaces, Replaces: vars.Replaces,
Provides: append(vars.Provides, vars.Name), Provides: append(vars.Provides, vars.Name),
Depends: deps, Depends: deps,
} }
pkgInfo.Section = vars.Group pkgInfo.Section = vars.Group.Resolved()
pkgFormat := input.PkgFormat() pkgFormat := input.PkgFormat()
info := input.OSRelease() info := input.OSRelease()
@@ -315,12 +225,12 @@ func buildPkgMetadata(
} }
if pkgFormat == "rpm" { if pkgFormat == "rpm" {
pkgInfo.RPM.Group = vars.Group pkgInfo.RPM.Group = vars.Group.Resolved()
if vars.Summary != "" { if vars.Summary.Resolved() != "" {
pkgInfo.RPM.Summary = vars.Summary pkgInfo.RPM.Summary = vars.Summary.Resolved()
} else { } else {
lines := strings.SplitN(vars.Description, "\n", 2) lines := strings.SplitN(vars.Description.Resolved(), "\n", 2)
pkgInfo.RPM.Summary = lines[0] pkgInfo.RPM.Summary = lines[0]
} }
} }
@@ -341,17 +251,17 @@ func buildPkgMetadata(
} }
pkgInfo.Overridables.Contents = contents pkgInfo.Overridables.Contents = contents
if len(vars.AutoProv) == 1 && decoder.IsTruthy(vars.AutoProv[0]) { if len(vars.AutoProv.Resolved()) == 1 && decoder.IsTruthy(vars.AutoProv.Resolved()[0]) {
f := finddeps.New(info, pkgFormat) f := finddeps.New(info, pkgFormat)
err = f.FindProvides(ctx, pkgInfo, dirs, vars.AutoProvSkipList) err = f.FindProvides(ctx, pkgInfo, dirs, vars.AutoProvSkipList.Resolved())
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
if len(vars.AutoReq) == 1 && decoder.IsTruthy(vars.AutoReq[0]) { if len(vars.AutoReq.Resolved()) == 1 && decoder.IsTruthy(vars.AutoReq.Resolved()[0]) {
f := finddeps.New(info, pkgFormat) f := finddeps.New(info, pkgFormat)
err = f.FindRequires(ctx, pkgInfo, dirs, vars.AutoReqSkipList) err = f.FindRequires(ctx, pkgInfo, dirs, vars.AutoReqSkipList.Resolved())
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -20,7 +20,7 @@ import (
"context" "context"
"path/filepath" "path/filepath"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/db" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
) )
type ScriptResolver struct { type ScriptResolver struct {
@@ -34,7 +34,7 @@ type ScriptInfo struct {
func (s *ScriptResolver) ResolveScript( func (s *ScriptResolver) ResolveScript(
ctx context.Context, ctx context.Context,
pkg *db.Package, pkg *alrsh.Package,
) *ScriptInfo { ) *ScriptInfo {
var repository, script string var repository, script string

View File

@@ -20,6 +20,7 @@ import (
"context" "context"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils" "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
) )
type ScriptViewerConfig interface { type ScriptViewerConfig interface {
@@ -33,12 +34,12 @@ type ScriptViewer struct {
func (s *ScriptViewer) ViewScript( func (s *ScriptViewer) ViewScript(
ctx context.Context, ctx context.Context,
input *BuildInput, input *BuildInput,
sf *ScriptFile, a *alrsh.ScriptFile,
basePkg string, basePkg string,
) error { ) error {
return cliutils.PromptViewScript( return cliutils.PromptViewScript(
ctx, ctx,
sf.Path, a.Path(),
basePkg, basePkg,
s.config.PagerStyle(), s.config.PagerStyle(),
input.opts.Interactive, input.opts.Interactive,

View File

@@ -33,34 +33,18 @@ import (
_ "github.com/goreleaser/nfpm/v2/arch" _ "github.com/goreleaser/nfpm/v2/arch"
_ "github.com/goreleaser/nfpm/v2/deb" _ "github.com/goreleaser/nfpm/v2/deb"
_ "github.com/goreleaser/nfpm/v2/rpm" _ "github.com/goreleaser/nfpm/v2/rpm"
"mvdan.cc/sh/v3/syntax"
"github.com/goreleaser/nfpm/v2" "github.com/goreleaser/nfpm/v2"
"github.com/goreleaser/nfpm/v2/files" "github.com/goreleaser/nfpm/v2/files"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cpu" "gitea.plemya-x.ru/Plemya-x/ALR/internal/cpu"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/manager" "gitea.plemya-x.ru/Plemya-x/ALR/internal/manager"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/overrides" "gitea.plemya-x.ru/Plemya-x/ALR/internal/overrides"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
) )
// Функция readScript анализирует скрипт сборки с использованием встроенной реализации bash
func readScript(script string) (*syntax.File, error) {
fl, err := os.Open(script) // Открываем файл скрипта
if err != nil {
return nil, err
}
defer fl.Close() // Закрываем файл после выполнения
file, err := syntax.NewParser().Parse(fl, "alr.sh") // Парсим скрипт с помощью синтаксического анализатора
if err != nil {
return nil, err
}
return file, nil // Возвращаем синтаксическое дерево
}
// Функция prepareDirs подготавливает директории для сборки. // Функция prepareDirs подготавливает директории для сборки.
func prepareDirs(dirs types.Directories) error { func prepareDirs(dirs types.Directories) error {
err := os.RemoveAll(dirs.BaseDir) // Удаляем базовую директорию, если она существует err := os.RemoveAll(dirs.BaseDir) // Удаляем базовую директорию, если она существует
@@ -76,7 +60,7 @@ func prepareDirs(dirs types.Directories) error {
// Функция buildContents создает секцию содержимого пакета, которая содержит файлы, // Функция buildContents создает секцию содержимого пакета, которая содержит файлы,
// которые будут включены в конечный пакет. // которые будут включены в конечный пакет.
func buildContents(vars *types.BuildVars, dirs types.Directories, preferedContents *[]string) ([]*files.Content, error) { func buildContents(vars *alrsh.Package, dirs types.Directories, preferedContents *[]string) ([]*files.Content, error) {
contents := []*files.Content{} contents := []*files.Content{}
processPath := func(path, trimmed string, prefered bool) error { processPath := func(path, trimmed string, prefered bool) error {
@@ -139,7 +123,7 @@ func buildContents(vars *types.BuildVars, dirs types.Directories, preferedConten
}, },
} }
if slices.Contains(vars.Backup, trimmed) { if slices.Contains(vars.Backup.Resolved(), trimmed) {
fileContent.Type = "config|noreplace" fileContent.Type = "config|noreplace"
} }
@@ -172,7 +156,7 @@ func buildContents(vars *types.BuildVars, dirs types.Directories, preferedConten
var RegexpALRPackageName = regexp.MustCompile(`^(?P<package>[^+]+)\+alr-(?P<repo>.+)$`) var RegexpALRPackageName = regexp.MustCompile(`^(?P<package>[^+]+)\+alr-(?P<repo>.+)$`)
func getBasePkgInfo(vars *types.BuildVars, input interface { func getBasePkgInfo(vars *alrsh.Package, input interface {
RepositoryProvider RepositoryProvider
OsInfoProvider OsInfoProvider
}, },
@@ -228,39 +212,39 @@ func createBuildEnvVars(info *distro.OSRelease, dirs types.Directories) []string
} }
// Функция setScripts добавляет скрипты-перехватчики к метаданным пакета. // Функция setScripts добавляет скрипты-перехватчики к метаданным пакета.
func setScripts(vars *types.BuildVars, info *nfpm.Info, scriptDir string) { func setScripts(vars *alrsh.Package, info *nfpm.Info, scriptDir string) {
if vars.Scripts.PreInstall != "" { if vars.Scripts.Resolved().PreInstall != "" {
info.Scripts.PreInstall = filepath.Join(scriptDir, vars.Scripts.PreInstall) info.Scripts.PreInstall = filepath.Join(scriptDir, vars.Scripts.Resolved().PreInstall)
} }
if vars.Scripts.PostInstall != "" { if vars.Scripts.Resolved().PostInstall != "" {
info.Scripts.PostInstall = filepath.Join(scriptDir, vars.Scripts.PostInstall) info.Scripts.PostInstall = filepath.Join(scriptDir, vars.Scripts.Resolved().PostInstall)
} }
if vars.Scripts.PreRemove != "" { if vars.Scripts.Resolved().PreRemove != "" {
info.Scripts.PreRemove = filepath.Join(scriptDir, vars.Scripts.PreRemove) info.Scripts.PreRemove = filepath.Join(scriptDir, vars.Scripts.Resolved().PreRemove)
} }
if vars.Scripts.PostRemove != "" { if vars.Scripts.Resolved().PostRemove != "" {
info.Scripts.PostRemove = filepath.Join(scriptDir, vars.Scripts.PostRemove) info.Scripts.PostRemove = filepath.Join(scriptDir, vars.Scripts.Resolved().PostRemove)
} }
if vars.Scripts.PreUpgrade != "" { if vars.Scripts.Resolved().PreUpgrade != "" {
info.ArchLinux.Scripts.PreUpgrade = filepath.Join(scriptDir, vars.Scripts.PreUpgrade) info.ArchLinux.Scripts.PreUpgrade = filepath.Join(scriptDir, vars.Scripts.Resolved().PreUpgrade)
info.APK.Scripts.PreUpgrade = filepath.Join(scriptDir, vars.Scripts.PreUpgrade) info.APK.Scripts.PreUpgrade = filepath.Join(scriptDir, vars.Scripts.Resolved().PreUpgrade)
} }
if vars.Scripts.PostUpgrade != "" { if vars.Scripts.Resolved().PostUpgrade != "" {
info.ArchLinux.Scripts.PostUpgrade = filepath.Join(scriptDir, vars.Scripts.PostUpgrade) info.ArchLinux.Scripts.PostUpgrade = filepath.Join(scriptDir, vars.Scripts.Resolved().PostUpgrade)
info.APK.Scripts.PostUpgrade = filepath.Join(scriptDir, vars.Scripts.PostUpgrade) info.APK.Scripts.PostUpgrade = filepath.Join(scriptDir, vars.Scripts.Resolved().PostUpgrade)
} }
if vars.Scripts.PreTrans != "" { if vars.Scripts.Resolved().PreTrans != "" {
info.RPM.Scripts.PreTrans = filepath.Join(scriptDir, vars.Scripts.PreTrans) info.RPM.Scripts.PreTrans = filepath.Join(scriptDir, vars.Scripts.Resolved().PreTrans)
} }
if vars.Scripts.PostTrans != "" { if vars.Scripts.Resolved().PostTrans != "" {
info.RPM.Scripts.PostTrans = filepath.Join(scriptDir, vars.Scripts.PostTrans) info.RPM.Scripts.PostTrans = filepath.Join(scriptDir, vars.Scripts.Resolved().PostTrans)
} }
} }

View File

@@ -26,9 +26,9 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils" "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config" "gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/db" "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/manager" "gitea.plemya-x.ru/Plemya-x/ALR/internal/manager"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/repos" "gitea.plemya-x.ru/Plemya-x/ALR/internal/repos"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
) )
type AppDeps struct { type AppDeps struct {
@@ -123,8 +123,15 @@ func (b *AppBuilder) withRepos(enablePull, forcePull bool) *AppBuilder {
cfg := b.deps.Cfg cfg := b.deps.Cfg
db := b.deps.DB db := b.deps.DB
if cfg == nil || db == nil { info := b.deps.Info
b.err = errors.New("config and db are required before initializing repos")
if info == nil {
b.WithDistroInfo()
info = b.deps.Info
}
if cfg == nil || db == nil || info == nil {
b.err = errors.New("config, db and info are required before initializing repos")
return b return b
} }

View File

@@ -28,8 +28,8 @@ import (
"github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2"
"github.com/leonelquinteros/gotext" "github.com/leonelquinteros/gotext"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/pager" "gitea.plemya-x.ru/Plemya-x/ALR/internal/pager"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
) )
// YesNoPrompt asks the user a yes or no question, using def as the default answer // YesNoPrompt asks the user a yes or no question, using def as the default answer
@@ -102,8 +102,8 @@ func ShowScript(path, name, style string) error {
// FlattenPkgs attempts to flatten the a map of slices of packages into a single slice // FlattenPkgs attempts to flatten the a map of slices of packages into a single slice
// of packages by prompting the user if multiple packages match. // of packages by prompting the user if multiple packages match.
func FlattenPkgs(ctx context.Context, found map[string][]db.Package, verb string, interactive bool) []db.Package { func FlattenPkgs(ctx context.Context, found map[string][]alrsh.Package, verb string, interactive bool) []alrsh.Package {
var outPkgs []db.Package var outPkgs []alrsh.Package
for _, pkgs := range found { for _, pkgs := range found {
if len(pkgs) > 1 && interactive { if len(pkgs) > 1 && interactive {
choice, err := PkgPrompt(ctx, pkgs, verb, interactive) choice, err := PkgPrompt(ctx, pkgs, verb, interactive)
@@ -120,7 +120,7 @@ func FlattenPkgs(ctx context.Context, found map[string][]db.Package, verb string
} }
// PkgPrompt asks the user to choose between multiple packages. // PkgPrompt asks the user to choose between multiple packages.
func PkgPrompt(ctx context.Context, options []db.Package, verb string, interactive bool) (db.Package, error) { func PkgPrompt(ctx context.Context, options []alrsh.Package, verb string, interactive bool) (alrsh.Package, error) {
if !interactive { if !interactive {
return options[0], nil return options[0], nil
} }
@@ -138,7 +138,7 @@ func PkgPrompt(ctx context.Context, options []db.Package, verb string, interacti
var choice int var choice int
err := survey.AskOne(prompt, &choice) err := survey.AskOne(prompt, &choice)
if err != nil { if err != nil {
return db.Package{}, err return alrsh.Package{}, err
} }
return options[choice], nil return options[choice], nil

View File

@@ -20,6 +20,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"log/slog" "log/slog"
"runtime/debug"
"github.com/leonelquinteros/gotext" "github.com/leonelquinteros/gotext"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
@@ -44,10 +45,12 @@ func HandleExitCoder(err error) {
slog.Error(err.Error()) slog.Error(err.Error())
} }
} }
debug.PrintStack()
cli.OsExiter(exitErr.ExitCode()) cli.OsExiter(exitErr.ExitCode())
return return
} }
debug.PrintStack()
slog.Error(err.Error()) slog.Error(err.Error())
cli.OsExiter(1) cli.OsExiter(1)
} }

View File

@@ -29,7 +29,7 @@ import (
"github.com/pelletier/go-toml/v2" "github.com/pelletier/go-toml/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/internal/types" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
) )
type ALRConfig struct { type ALRConfig struct {

View File

@@ -23,41 +23,18 @@ import (
"context" "context"
"log/slog" "log/slog"
"github.com/jmoiron/sqlx"
"github.com/leonelquinteros/gotext" "github.com/leonelquinteros/gotext"
_ "modernc.org/sqlite"
"xorm.io/xorm"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config" "gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
) )
// CurrentVersion is the current version of the database. const CurrentVersion = 5
// The database is reset if its version doesn't match this.
const CurrentVersion = 4
// Package is a ALR package's database representation type Version struct {
type Package struct { Version int `xorm:"'version'"`
BasePkgName string `sh:"base" db:"basepkg_name"`
Name string `sh:"name,required" db:"name"`
Version string `sh:"version,required" db:"version"`
Release int `sh:"release,required" db:"release"`
Epoch uint `sh:"epoch" db:"epoch"`
Summary JSON[map[string]string] `db:"summary"`
Description JSON[map[string]string] `db:"description"`
Group JSON[map[string]string] `db:"group_name"`
Homepage JSON[map[string]string] `db:"homepage"`
Maintainer JSON[map[string]string] `db:"maintainer"`
Architectures JSON[[]string] `sh:"architectures" db:"architectures"`
Licenses JSON[[]string] `sh:"license" db:"licenses"`
Provides JSON[[]string] `sh:"provides" db:"provides"`
Conflicts JSON[[]string] `sh:"conflicts" db:"conflicts"`
Replaces JSON[[]string] `sh:"replaces" db:"replaces"`
Depends JSON[map[string][]string] `db:"depends"`
BuildDepends JSON[map[string][]string] `db:"builddepends"`
OptDepends JSON[map[string][]string] `db:"optdepends"`
Repository string `db:"repository"`
}
type version struct {
Version int `db:"version"`
} }
type Config interface { type Config interface {
@@ -65,7 +42,7 @@ type Config interface {
} }
type Database struct { type Database struct {
conn *sqlx.DB engine *xorm.Engine
config Config config Config
} }
@@ -75,181 +52,100 @@ func New(config Config) *Database {
} }
} }
func (d *Database) Init(ctx context.Context) error { func (d *Database) Connect() error {
err := d.Connect(ctx)
if err != nil {
return err
}
return d.initDB(ctx)
}
func (d *Database) Connect(ctx context.Context) error {
dsn := d.config.GetPaths().DBPath dsn := d.config.GetPaths().DBPath
db, err := sqlx.Open("sqlite", dsn) engine, err := xorm.NewEngine("sqlite", dsn)
// engine.SetLogLevel(log.LOG_DEBUG)
// engine.ShowSQL(true)
if err != nil { if err != nil {
return err return err
} }
d.conn = db d.engine = engine
return nil return nil
} }
func (d *Database) GetConn() *sqlx.DB { func (d *Database) Init(ctx context.Context) error {
return d.conn if err := d.Connect(); err != nil {
} return err
}
func (d *Database) initDB(ctx context.Context) error { if err := d.engine.Sync2(new(alrsh.Package), new(Version)); err != nil {
d.conn = d.conn.Unsafe()
conn := d.conn
_, err := conn.ExecContext(ctx, `
CREATE TABLE IF NOT EXISTS pkgs (
basepkg_name TEXT NOT NULL,
name TEXT NOT NULL,
repository TEXT NOT NULL,
version TEXT NOT NULL,
release INT NOT NULL,
epoch INT,
summary TEXT CHECK(summary = 'null' OR (JSON_VALID(summary) AND JSON_TYPE(summary) = 'object')),
description TEXT CHECK(description = 'null' OR (JSON_VALID(description) AND JSON_TYPE(description) = 'object')),
group_name TEXT CHECK(group_name = 'null' OR (JSON_VALID(group_name) AND JSON_TYPE(group_name) = 'object')),
homepage TEXT CHECK(homepage = 'null' OR (JSON_VALID(homepage) AND JSON_TYPE(homepage) = 'object')),
maintainer TEXT CHECK(maintainer = 'null' OR (JSON_VALID(maintainer) AND JSON_TYPE(maintainer) = 'object')),
architectures TEXT CHECK(architectures = 'null' OR (JSON_VALID(architectures) AND JSON_TYPE(architectures) = 'array')),
licenses TEXT CHECK(licenses = 'null' OR (JSON_VALID(licenses) AND JSON_TYPE(licenses) = 'array')),
provides TEXT CHECK(provides = 'null' OR (JSON_VALID(provides) AND JSON_TYPE(provides) = 'array')),
conflicts TEXT CHECK(conflicts = 'null' OR (JSON_VALID(conflicts) AND JSON_TYPE(conflicts) = 'array')),
replaces TEXT CHECK(replaces = 'null' OR (JSON_VALID(replaces) AND JSON_TYPE(replaces) = 'array')),
depends TEXT CHECK(depends = 'null' OR (JSON_VALID(depends) AND JSON_TYPE(depends) = 'object')),
builddepends TEXT CHECK(builddepends = 'null' OR (JSON_VALID(builddepends) AND JSON_TYPE(builddepends) = 'object')),
optdepends TEXT CHECK(optdepends = 'null' OR (JSON_VALID(optdepends) AND JSON_TYPE(optdepends) = 'object')),
UNIQUE(name, repository)
);
CREATE TABLE IF NOT EXISTS alr_db_version (
version INT NOT NULL
);
`)
if err != nil {
return err return err
} }
ver, ok := d.GetVersion(ctx) ver, ok := d.GetVersion(ctx)
if ok && ver != CurrentVersion { if ok && ver != CurrentVersion {
slog.Warn(gotext.Get("Database version mismatch; resetting"), "version", ver, "expected", CurrentVersion) slog.Warn(gotext.Get("Database version mismatch; resetting"), "version", ver, "expected", CurrentVersion)
err = d.reset(ctx) if err := d.reset(); err != nil {
if err != nil {
return err return err
} }
return d.initDB(ctx) return d.Init(ctx)
} else if !ok { } else if !ok {
slog.Warn(gotext.Get("Database version does not exist. Run alr fix if something isn't working."), "version", ver, "expected", CurrentVersion) slog.Warn(gotext.Get("Database version does not exist. Run alr fix if something isn't working."))
return d.addVersion(ctx, CurrentVersion) return d.addVersion(CurrentVersion)
} }
return nil return nil
} }
func (d *Database) GetVersion(ctx context.Context) (int, bool) { func (d *Database) GetVersion(ctx context.Context) (int, bool) {
var ver version var v Version
err := d.conn.GetContext(ctx, &ver, "SELECT * FROM alr_db_version LIMIT 1;") has, err := d.engine.Get(&v)
if err != nil { if err != nil || !has {
return 0, false return 0, false
} }
return ver.Version, true return v.Version, true
} }
func (d *Database) addVersion(ctx context.Context, ver int) error { func (d *Database) addVersion(ver int) error {
_, err := d.conn.ExecContext(ctx, `INSERT INTO alr_db_version(version) VALUES (?);`, ver) _, err := d.engine.Insert(&Version{Version: ver})
return err return err
} }
func (d *Database) reset(ctx context.Context) error { func (d *Database) reset() error {
_, err := d.conn.ExecContext(ctx, "DROP TABLE IF EXISTS pkgs;") return d.engine.DropTables(new(alrsh.Package), new(Version))
}
func (d *Database) InsertPackage(ctx context.Context, pkg alrsh.Package) error {
session := d.engine.Context(ctx)
affected, err := session.Where("name = ? AND repository = ?", pkg.Name, pkg.Repository).Update(&pkg)
if err != nil { if err != nil {
return err return err
} }
_, err = d.conn.ExecContext(ctx, "DROP TABLE IF EXISTS alr_db_version;")
if affected == 0 {
_, err = session.Insert(&pkg)
if err != nil {
return err return err
}
}
return nil
} }
func (d *Database) GetPkgs(ctx context.Context, where string, args ...any) (*sqlx.Rows, error) { func (d *Database) GetPkgs(_ context.Context, where string, args ...any) ([]alrsh.Package, error) {
stream, err := d.conn.QueryxContext(ctx, "SELECT * FROM pkgs WHERE "+where, args...) var pkgs []alrsh.Package
if err != nil { err := d.engine.Where(where, args...).Find(&pkgs)
return pkgs, err
}
func (d *Database) GetPkg(where string, args ...any) (*alrsh.Package, error) {
var pkg alrsh.Package
has, err := d.engine.Where(where, args...).Get(&pkg)
if err != nil || !has {
return nil, err return nil, err
} }
return stream, nil return &pkg, nil
} }
func (d *Database) GetPkg(ctx context.Context, where string, args ...any) (*Package, error) { func (d *Database) DeletePkgs(_ context.Context, where string, args ...any) error {
out := &Package{} _, err := d.engine.Where(where, args...).Delete(&alrsh.Package{})
err := d.conn.GetContext(ctx, out, "SELECT * FROM pkgs WHERE "+where+" LIMIT 1", args...)
return out, err
}
func (d *Database) DeletePkgs(ctx context.Context, where string, args ...any) error {
_, err := d.conn.ExecContext(ctx, "DELETE FROM pkgs WHERE "+where, args...)
return err return err
} }
func (d *Database) IsEmpty(ctx context.Context) bool { func (d *Database) IsEmpty() bool {
var count int count, err := d.engine.Count(new(alrsh.Package))
err := d.conn.GetContext(ctx, &count, "SELECT count(1) FROM pkgs;") return err != nil || count == 0
if err != nil {
return true
}
return count == 0
}
func (d *Database) InsertPackage(ctx context.Context, pkg Package) error {
_, err := d.conn.NamedExecContext(ctx, `
INSERT OR REPLACE INTO pkgs (
basepkg_name,
name,
repository,
version,
release,
epoch,
summary,
description,
group_name,
homepage,
maintainer,
architectures,
licenses,
provides,
conflicts,
replaces,
depends,
builddepends,
optdepends
) VALUES (
:basepkg_name,
:name,
:repository,
:version,
:release,
:epoch,
:summary,
:description,
:group_name,
:homepage,
:maintainer,
:architectures,
:licenses,
:provides,
:conflicts,
:replaces,
:depends,
:builddepends,
:optdepends
);
`, pkg)
return err
} }
func (d *Database) Close() error { func (d *Database) Close() error {
if d.conn != nil { return d.engine.Close()
return d.conn.Close()
} else {
return nil
}
} }

View File

@@ -25,10 +25,11 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/jmoiron/sqlx" "github.com/stretchr/testify/assert"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config" "gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/db" "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
) )
type TestALRConfig struct{} type TestALRConfig struct{}
@@ -45,35 +46,38 @@ func prepareDb() *db.Database {
return database return database
} }
var testPkg = db.Package{ var testPkg = alrsh.Package{
Name: "test", Name: "test",
Version: "0.0.1", Version: "0.0.1",
Release: 1, Release: 1,
Epoch: 2, Epoch: 2,
Description: db.NewJSON(map[string]string{ Description: alrsh.OverridableFromMap(map[string]string{
"en": "Test package", "en": "Test package",
"ru": "Проверочный пакет", "ru": "Проверочный пакет",
}), }),
Homepage: db.NewJSON(map[string]string{ Homepage: alrsh.OverridableFromMap(map[string]string{
"en": "https://gitea.plemya-x.ru/xpamych/ALR", "en": "https://gitea.plemya-x.ru/xpamych/ALR",
}), }),
Maintainer: db.NewJSON(map[string]string{ Maintainer: alrsh.OverridableFromMap(map[string]string{
"en": "Evgeniy Khramov <xpamych@yandex.ru>", "en": "Evgeniy Khramov <xpamych@yandex.ru>",
"ru": "Евгений Храмов <xpamych@yandex.ru>", "ru": "Евгений Храмов <xpamych@yandex.ru>",
}), }),
Architectures: db.NewJSON([]string{"arm64", "amd64"}), Architectures: []string{"arm64", "amd64"},
Licenses: db.NewJSON([]string{"GPL-3.0-or-later"}), Licenses: []string{"GPL-3.0-or-later"},
Provides: db.NewJSON([]string{"test"}), Provides: []string{"test"},
Conflicts: db.NewJSON([]string{"test"}), Conflicts: []string{"test"},
Replaces: db.NewJSON([]string{"test-old"}), Replaces: []string{"test-old"},
Depends: db.NewJSON(map[string][]string{ Depends: alrsh.OverridableFromMap(map[string][]string{
"": {"sudo"}, "": {"sudo"},
}), }),
BuildDepends: db.NewJSON(map[string][]string{ BuildDepends: alrsh.OverridableFromMap(map[string][]string{
"": {"golang"}, "": {"golang"},
"arch": {"go"}, "arch": {"go"},
}), }),
Repository: "default", Repository: "default",
Summary: alrsh.OverridableFromMap(map[string]string{}),
Group: alrsh.OverridableFromMap(map[string]string{}),
OptDepends: alrsh.OverridableFromMap(map[string][]string{}),
} }
func TestInit(t *testing.T) { func TestInit(t *testing.T) {
@@ -99,15 +103,16 @@ func TestInsertPackage(t *testing.T) {
t.Fatalf("Expected no error, got %s", err) t.Fatalf("Expected no error, got %s", err)
} }
dbPkg := db.Package{} pkgs, err := database.GetPkgs(ctx, "name = 'test' AND repository = 'default'")
err = sqlx.Get(database.GetConn(), &dbPkg, "SELECT * FROM pkgs WHERE name = 'test' AND repository = 'default'")
if err != nil { if err != nil {
t.Fatalf("Expected no error, got %s", err) t.Fatalf("Expected no error, got %s", err)
} }
if !reflect.DeepEqual(testPkg, dbPkg) { if len(pkgs) != 1 {
t.Errorf("Expected test package to be the same as database package") t.Fatalf("Expected 1 package, got %d", len(pkgs))
} }
assert.Equal(t, testPkg, pkgs[0])
} }
func TestGetPkgs(t *testing.T) { func TestGetPkgs(t *testing.T) {
@@ -130,18 +135,12 @@ func TestGetPkgs(t *testing.T) {
t.Errorf("Expected no error, got %s", err) t.Errorf("Expected no error, got %s", err)
} }
result, err := database.GetPkgs(ctx, "name LIKE 'x%'") pkgs, err := database.GetPkgs(ctx, "name LIKE 'x%'")
if err != nil { if err != nil {
t.Fatalf("Expected no error, got %s", err) t.Fatalf("Expected no error, got %s", err)
} }
for result.Next() { for _, dbPkg := range pkgs {
var dbPkg db.Package
err = result.StructScan(&dbPkg)
if err != nil {
t.Errorf("Expected no error, got %s", err)
}
if !strings.HasPrefix(dbPkg.Name, "x") { if !strings.HasPrefix(dbPkg.Name, "x") {
t.Errorf("Expected package name to start with 'x', got %s", dbPkg.Name) t.Errorf("Expected package name to start with 'x', got %s", dbPkg.Name)
} }
@@ -168,7 +167,7 @@ func TestGetPkg(t *testing.T) {
t.Errorf("Expected no error, got %s", err) t.Errorf("Expected no error, got %s", err)
} }
pkg, err := database.GetPkg(ctx, "name LIKE 'x%' ORDER BY name") pkg, err := database.GetPkg("name LIKE 'x%'")
if err != nil { if err != nil {
t.Fatalf("Expected no error, got %s", err) t.Fatalf("Expected no error, got %s", err)
} }
@@ -206,16 +205,6 @@ func TestDeletePkgs(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("Expected no error, got %s", err) t.Errorf("Expected no error, got %s", err)
} }
var dbPkg db.Package
err = database.GetConn().Get(&dbPkg, "SELECT * FROM pkgs WHERE name LIKE 'x%' ORDER BY name LIMIT 1;")
if err != nil {
t.Errorf("Expected no error, got %s", err)
}
if dbPkg.Name != "x2" {
t.Errorf("Expected x2 package, got %s", dbPkg.Name)
}
} }
func TestJsonArrayContains(t *testing.T) { func TestJsonArrayContains(t *testing.T) {
@@ -227,7 +216,7 @@ func TestJsonArrayContains(t *testing.T) {
x1.Name = "x1" x1.Name = "x1"
x2 := testPkg x2 := testPkg
x2.Name = "x2" x2.Name = "x2"
x2.Provides.Val = append(x2.Provides.Val, "x") x2.Provides = append(x2.Provides, "x")
err := database.InsertPackage(ctx, x1) err := database.InsertPackage(ctx, x1)
if err != nil { if err != nil {
@@ -239,13 +228,24 @@ func TestJsonArrayContains(t *testing.T) {
t.Errorf("Expected no error, got %s", err) t.Errorf("Expected no error, got %s", err)
} }
var dbPkg db.Package pkgs, err := database.GetPkgs(ctx, "name = 'x2'")
err = database.GetConn().Get(&dbPkg, "SELECT * FROM pkgs WHERE json_array_contains(provides, 'x');")
if err != nil { if err != nil {
t.Fatalf("Expected no error, got %s", err) t.Fatalf("Expected no error, got %s", err)
} }
if dbPkg.Name != "x2" { if len(pkgs) != 1 || pkgs[0].Name != "x2" {
t.Errorf("Expected x2 package, got %s", dbPkg.Name) t.Errorf("Expected x2 package, got %v", pkgs)
}
// Verify the provides field contains 'x'
found := false
for _, p := range pkgs[0].Provides {
if p == "x" {
found = true
break
}
}
if !found {
t.Errorf("Expected provides to contain 'x'")
} }
} }

View File

@@ -1,80 +0,0 @@
// 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 db
import (
"database/sql"
"database/sql/driver"
"encoding/json"
"errors"
"fmt"
)
// JSON represents a JSON value in the database
type JSON[T any] struct {
Val T
}
// NewJSON creates a new database JSON value
func NewJSON[T any](v T) JSON[T] {
return JSON[T]{Val: v}
}
func (s *JSON[T]) Scan(val any) error {
if val == nil {
return nil
}
switch val := val.(type) {
case string:
err := json.Unmarshal([]byte(val), &s.Val)
if err != nil {
return err
}
case sql.NullString:
if val.Valid {
err := json.Unmarshal([]byte(val.String), &s.Val)
if err != nil {
return err
}
}
default:
return errors.New("sqlite json types must be strings")
}
return nil
}
func (s JSON[T]) Value() (driver.Value, error) {
data, err := json.Marshal(s.Val)
if err != nil {
return nil, err
}
return string(data), nil
}
func (s JSON[T]) MarshalYAML() (any, error) {
return s.Val, nil
}
func (s JSON[T]) String() string {
return fmt.Sprint(s.Val)
}
func (s JSON[T]) GoString() string {
return fmt.Sprintf("%#v", s.Val)
}

View File

@@ -21,7 +21,6 @@ package overrides
import ( import (
"fmt" "fmt"
"reflect"
"regexp" "regexp"
"strings" "strings"
@@ -29,8 +28,7 @@ import (
"golang.org/x/text/language" "golang.org/x/text/language"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cpu" "gitea.plemya-x.ru/Plemya-x/ALR/internal/cpu"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/db" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/distro"
) )
type Opts struct { type Opts struct {
@@ -150,65 +148,6 @@ func (o *Opts) WithLanguageTags(langs []string) *Opts {
return out return out
} }
// ResolvedPackage is a ALR package after its overrides
// have been resolved
type ResolvedPackage struct {
Name string `sh:"name"`
Version string `sh:"version"`
Release int `sh:"release"`
Epoch uint `sh:"epoch"`
Group string `db:"group_name"`
Summary string `db:"summary"`
Description string `db:"description"`
Homepage string `db:"homepage"`
Maintainer string `db:"maintainer"`
Architectures []string `sh:"architectures"`
Licenses []string `sh:"license"`
Provides []string `sh:"provides"`
Conflicts []string `sh:"conflicts"`
Replaces []string `sh:"replaces"`
Depends []string `sh:"deps"`
BuildDepends []string `sh:"build_deps"`
OptDepends []string `sh:"opt_deps"`
}
func ResolvePackage(pkg *db.Package, overrides []string) *ResolvedPackage {
out := &ResolvedPackage{}
outVal := reflect.ValueOf(out).Elem()
pkgVal := reflect.ValueOf(pkg).Elem()
for i := 0; i < outVal.NumField(); i++ {
fieldVal := outVal.Field(i)
fieldType := fieldVal.Type()
pkgFieldVal := pkgVal.FieldByName(outVal.Type().Field(i).Name)
pkgFieldType := pkgFieldVal.Type()
if strings.HasPrefix(pkgFieldType.String(), "db.JSON") {
pkgFieldVal = pkgFieldVal.FieldByName("Val")
pkgFieldType = pkgFieldVal.Type()
}
if pkgFieldType.AssignableTo(fieldType) {
fieldVal.Set(pkgFieldVal)
continue
}
if pkgFieldVal.Kind() == reflect.Map && pkgFieldType.Elem().AssignableTo(fieldType) {
for _, override := range overrides {
overrideVal := pkgFieldVal.MapIndex(reflect.ValueOf(override))
if !overrideVal.IsValid() {
continue
}
fieldVal.Set(overrideVal)
break
}
}
}
return out
}
func parseLangs(langs []string, tags []language.Tag) ([]string, error) { func parseLangs(langs []string, tags []language.Tag) ([]string, error) {
out := make([]string, len(tags)+len(langs)) out := make([]string, len(tags)+len(langs))
for i, tag := range tags { for i, tag := range tags {

View File

@@ -27,8 +27,8 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"golang.org/x/text/language" "golang.org/x/text/language"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/overrides" "gitea.plemya-x.ru/Plemya-x/ALR/internal/overrides"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
) )
var info = &distro.OSRelease{ var info = &distro.OSRelease{

View File

@@ -22,11 +22,11 @@ package repos
import ( import (
"context" "context"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/db" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
) )
func (rs *Repos) FindPkgs(ctx context.Context, pkgs []string) (map[string][]db.Package, []string, error) { func (rs *Repos) FindPkgs(ctx context.Context, pkgs []string) (map[string][]alrsh.Package, []string, error) {
found := map[string][]db.Package{} found := map[string][]alrsh.Package{}
notFound := []string(nil) notFound := []string(nil)
for _, pkgName := range pkgs { for _, pkgName := range pkgs {
@@ -40,17 +40,10 @@ func (rs *Repos) FindPkgs(ctx context.Context, pkgs []string) (map[string][]db.P
} }
added := 0 added := 0
for result.Next() { for _, pkg := range result {
var pkg db.Package
err = result.StructScan(&pkg)
if err != nil {
return nil, nil, err
}
added++ added++
found[pkgName] = append(found[pkgName], pkg) found[pkgName] = append(found[pkgName], pkg)
} }
result.Close()
if added == 0 { if added == 0 {
result, err := rs.db.GetPkgs(ctx, "name LIKE ?", pkgName) result, err := rs.db.GetPkgs(ctx, "name LIKE ?", pkgName)
@@ -58,18 +51,10 @@ func (rs *Repos) FindPkgs(ctx context.Context, pkgs []string) (map[string][]db.P
return nil, nil, err return nil, nil, err
} }
for result.Next() { for _, pkg := range result {
var pkg db.Package
err = result.StructScan(&pkg)
if err != nil {
return nil, nil, err
}
added++ added++
found[pkgName] = append(found[pkgName], pkg) found[pkgName] = append(found[pkgName], pkg)
} }
result.Close()
} }
if added == 0 { if added == 0 {

View File

@@ -24,9 +24,9 @@ import (
"strings" "strings"
"testing" "testing"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/repos" "gitea.plemya-x.ru/Plemya-x/ALR/internal/repos"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
) )
func TestFindPkgs(t *testing.T) { func TestFindPkgs(t *testing.T) {
@@ -89,31 +89,31 @@ func TestFindPkgsEmpty(t *testing.T) {
e.Db, e.Db,
) )
err := e.Db.InsertPackage(e.Ctx, db.Package{ err := e.Db.InsertPackage(e.Ctx, alrsh.Package{
Name: "test1", Name: "test1",
Repository: "default", Repository: "default",
Version: "0.0.1", Version: "0.0.1",
Release: 1, Release: 1,
Description: db.NewJSON(map[string]string{ Provides: []string{""},
Description: alrsh.OverridableFromMap(map[string]string{
"en": "Test package 1", "en": "Test package 1",
"ru": "Проверочный пакет 1", "ru": "Проверочный пакет 1",
}), }),
Provides: db.NewJSON([]string{""}),
}) })
if err != nil { if err != nil {
t.Fatalf("Expected no error, got %s", err) t.Fatalf("Expected no error, got %s", err)
} }
err = e.Db.InsertPackage(e.Ctx, db.Package{ err = e.Db.InsertPackage(e.Ctx, alrsh.Package{
Name: "test2", Name: "test2",
Repository: "default", Repository: "default",
Version: "0.0.1", Version: "0.0.1",
Release: 1, Release: 1,
Description: db.NewJSON(map[string]string{ Provides: []string{"test"},
Description: alrsh.OverridableFromMap(map[string]string{
"en": "Test package 2", "en": "Test package 2",
"ru": "Проверочный пакет 2", "ru": "Проверочный пакет 2",
}), }),
Provides: db.NewJSON([]string{"test"}),
}) })
if err != nil { if err != nil {
t.Fatalf("Expected no error, got %s", err) t.Fatalf("Expected no error, got %s", err)

View File

@@ -44,7 +44,7 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config" "gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/handlers" "gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/handlers"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
) )
type actionType uint8 type actionType uint8
@@ -130,7 +130,7 @@ func (rs *Repos) Pull(ctx context.Context, repos []types.Repo) error {
// If the DB was not present at startup, that means it's // If the DB was not present at startup, that means it's
// empty. In this case, we need to update the DB fully // empty. In this case, we need to update the DB fully
// rather than just incrementally. // rather than just incrementally.
if rs.db.IsEmpty(ctx) { if rs.db.IsEmpty() {
err = rs.processRepoFull(ctx, repo, repoDir) err = rs.processRepoFull(ctx, repo, repoDir)
if err != nil { if err != nil {
return err return err

View File

@@ -27,7 +27,8 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config" "gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/db" "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
) )
type TestALRConfig struct{} type TestALRConfig struct{}
@@ -84,16 +85,10 @@ build_deps=('golang')
result, err := database.GetPkgs(ctx, "1 = 1") result, err := database.GetPkgs(ctx, "1 = 1")
assert.NoError(t, err) assert.NoError(t, err)
pkgCount := 0 pkgCount := 0
for result.Next() { for _, pkg := range result {
var dbPkg db.Package assert.Equal(t, "foo", pkg.Name)
err = result.StructScan(&dbPkg) assert.Equal(t, alrsh.OverridableFromMap(map[string]string{"": "main desc"}), pkg.Description)
if err != nil { assert.Equal(t, alrsh.OverridableFromMap(map[string][]string{"": {"sudo"}}), pkg.Depends)
t.Errorf("Expected no error, got %s", err)
}
assert.Equal(t, "foo", dbPkg.Name)
assert.Equal(t, db.NewJSON(map[string]string{"": "main desc"}), dbPkg.Description)
assert.Equal(t, db.NewJSON(map[string][]string{"": {"sudo"}}), dbPkg.Depends)
pkgCount++ pkgCount++
} }
assert.Equal(t, 1, pkgCount) assert.Equal(t, 1, pkgCount)
@@ -125,20 +120,18 @@ meta_buz() {
assert.NoError(t, err) assert.NoError(t, err)
pkgCount := 0 pkgCount := 0
for result.Next() { for _, pkg := range result {
var dbPkg db.Package
err = result.StructScan(&dbPkg)
if err != nil { if err != nil {
t.Errorf("Expected no error, got %s", err) t.Errorf("Expected no error, got %s", err)
} }
if dbPkg.Name == "bar" { if pkg.Name == "bar" {
assert.Equal(t, db.NewJSON(map[string]string{"": "foo desc"}), dbPkg.Description) assert.Equal(t, alrsh.OverridableFromMap(map[string]string{"": "foo desc"}), pkg.Description)
assert.Equal(t, db.NewJSON(map[string][]string{"": {"sudo"}}), dbPkg.Depends) assert.Equal(t, alrsh.OverridableFromMap(map[string][]string{"": {"sudo"}}), pkg.Depends)
} }
if dbPkg.Name == "buz" { if pkg.Name == "buz" {
assert.Equal(t, db.NewJSON(map[string]string{"": "main desc"}), dbPkg.Description) assert.Equal(t, alrsh.OverridableFromMap(map[string]string{"": "main desc"}), pkg.Description)
assert.Equal(t, db.NewJSON(map[string][]string{"": {"sudo", "doas"}}), dbPkg.Depends) assert.Equal(t, alrsh.OverridableFromMap(map[string][]string{"": {"sudo", "doas"}}), pkg.Depends)
} }
pkgCount++ pkgCount++
} }

View File

@@ -29,7 +29,7 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/db" "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
database "gitea.plemya-x.ru/Plemya-x/ALR/internal/db" database "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/repos" "gitea.plemya-x.ru/Plemya-x/ALR/internal/repos"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
) )
type TestEnv struct { type TestEnv struct {
@@ -129,15 +129,7 @@ func TestPull(t *testing.T) {
t.Fatalf("Expected no error, got %s", err) t.Fatalf("Expected no error, got %s", err)
} }
var pkgAmt int pkgAmt := len(result)
for result.Next() {
var dbPkg db.Package
err = result.StructScan(&dbPkg)
if err != nil {
t.Errorf("Expected no error, got %s", err)
}
pkgAmt++
}
if pkgAmt == 0 { if pkgAmt == 0 {
t.Errorf("Expected at least 1 matching package, but got %d", pkgAmt) t.Errorf("Expected at least 1 matching package, but got %d", pkgAmt)

View File

@@ -19,7 +19,7 @@ package repos
import ( import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config" "gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
database "gitea.plemya-x.ru/Plemya-x/ALR/internal/db" database "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
) )
type Config interface { type Config interface {

View File

@@ -18,12 +18,9 @@ package repos
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"io" "io"
"path/filepath" "path/filepath"
"reflect"
"strings"
"github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing"
@@ -34,11 +31,9 @@ import (
"mvdan.cc/sh/v3/interp" "mvdan.cc/sh/v3/interp"
"mvdan.cc/sh/v3/syntax" "mvdan.cc/sh/v3/syntax"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/db" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/distro" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/parser" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/decoder"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types"
) )
// isValid makes sure the path of the file being updated is valid. // isValid makes sure the path of the file being updated is valid.
@@ -63,150 +58,19 @@ func parseScript(
syntaxParser *syntax.Parser, syntaxParser *syntax.Parser,
runner *interp.Runner, runner *interp.Runner,
r io.ReadCloser, r io.ReadCloser,
) ([]*db.Package, error) { ) ([]*alrsh.Package, error) {
fl, err := syntaxParser.Parse(r, "alr.sh") f, err := alrsh.ReadFromIOReader(r, "/tmp")
if err != nil { if err != nil {
return nil, err return nil, err
} }
_, dbPkgs, err := f.ParseBuildVars(ctx, &distro.OSRelease{}, []string{})
runner.Reset()
err = runner.Run(ctx, fl)
if err != nil { if err != nil {
return nil, err return nil, err
} }
for _, pkg := range dbPkgs {
d := decoder.New(&distro.OSRelease{}, runner) pkg.Repository = repo.Name
d.Overrides = false
d.LikeDistros = false
pkgNames, err := parser.ParseNames(d)
if err != nil {
return nil, fmt.Errorf("failed parsing package names: %w", err)
} }
if len(pkgNames.Names) == 0 {
return nil, errors.New("package name is missing")
}
var dbPkgs []*db.Package
if len(pkgNames.Names) > 1 {
if pkgNames.BasePkgName == "" {
pkgNames.BasePkgName = pkgNames.Names[0]
}
for _, pkgName := range pkgNames.Names {
pkgInfo := PackageInfo{}
funcName := fmt.Sprintf("meta_%s", pkgName)
runner.Reset()
err = runner.Run(ctx, fl)
if err != nil {
return nil, err
}
meta, ok := d.GetFuncWithSubshell(funcName)
if !ok {
return nil, fmt.Errorf("func %s is missing", funcName)
}
r, err := meta(ctx)
if err != nil {
return nil, err
}
d := decoder.New(&distro.OSRelease{}, r)
d.Overrides = false
d.LikeDistros = false
err = d.DecodeVars(&pkgInfo)
if err != nil {
return nil, err
}
pkg := pkgInfo.ToPackage(repo.Name)
resolveOverrides(r, pkg)
pkg.Name = pkgName
pkg.BasePkgName = pkgNames.BasePkgName
dbPkgs = append(dbPkgs, pkg)
}
return dbPkgs, nil return dbPkgs, nil
}
pkg := EmptyPackage(repo.Name)
err = d.DecodeVars(pkg)
if err != nil {
return nil, err
}
resolveOverrides(runner, pkg)
dbPkgs = append(dbPkgs, pkg)
return dbPkgs, nil
}
type PackageInfo struct {
Version string `sh:"version,required"`
Release int `sh:"release,required"`
Epoch uint `sh:"epoch"`
Architectures db.JSON[[]string] `sh:"architectures"`
Licenses db.JSON[[]string] `sh:"license"`
Provides db.JSON[[]string] `sh:"provides"`
Conflicts db.JSON[[]string] `sh:"conflicts"`
Replaces db.JSON[[]string] `sh:"replaces"`
}
func (inf *PackageInfo) ToPackage(repoName string) *db.Package {
pkg := EmptyPackage(repoName)
pkg.Version = inf.Version
pkg.Release = inf.Release
pkg.Epoch = inf.Epoch
pkg.Architectures = inf.Architectures
pkg.Licenses = inf.Licenses
pkg.Provides = inf.Provides
pkg.Conflicts = inf.Conflicts
pkg.Replaces = inf.Replaces
return pkg
}
func EmptyPackage(repoName string) *db.Package {
return &db.Package{
Group: db.NewJSON(map[string]string{}),
Summary: db.NewJSON(map[string]string{}),
Description: db.NewJSON(map[string]string{}),
Homepage: db.NewJSON(map[string]string{}),
Maintainer: db.NewJSON(map[string]string{}),
Depends: db.NewJSON(map[string][]string{}),
BuildDepends: db.NewJSON(map[string][]string{}),
Repository: repoName,
}
}
var overridable = map[string]string{
"deps": "Depends",
"build_deps": "BuildDepends",
"desc": "Description",
"homepage": "Homepage",
"maintainer": "Maintainer",
"group": "Group",
"summary": "Summary",
}
func resolveOverrides(runner *interp.Runner, pkg *db.Package) {
pkgVal := reflect.ValueOf(pkg).Elem()
for name, val := range runner.Vars {
for prefix, field := range overridable {
if strings.HasPrefix(name, prefix) {
override := strings.TrimPrefix(name, prefix)
override = strings.TrimPrefix(override, "_")
field := pkgVal.FieldByName(field)
varVal := field.FieldByName("Val")
varType := varVal.Type()
switch varType.Elem().String() {
case "[]string":
varVal.SetMapIndex(reflect.ValueOf(override), reflect.ValueOf(val.List))
case "string":
varVal.SetMapIndex(reflect.ValueOf(override), reflect.ValueOf(val.Str))
}
break
}
}
}
} }
func getHeadReference(r *git.Repository) (plumbing.ReferenceName, error) { func getHeadReference(r *git.Repository) (plumbing.ReferenceName, error) {

View File

@@ -22,13 +22,11 @@ package search
import ( import (
"context" "context"
"github.com/jmoiron/sqlx" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
database "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
) )
type PackagesProvider interface { type PackagesProvider interface {
GetPkgs(ctx context.Context, where string, args ...any) (*sqlx.Rows, error) GetPkgs(ctx context.Context, where string, args ...any) ([]alrsh.Package, error)
} }
type Searcher struct { type Searcher struct {
@@ -44,23 +42,8 @@ func New(pp PackagesProvider) *Searcher {
func (s *Searcher) Search( func (s *Searcher) Search(
ctx context.Context, ctx context.Context,
opts *SearchOptions, opts *SearchOptions,
) ([]database.Package, error) { ) ([]alrsh.Package, error) {
var packages []database.Package
where, args := opts.WhereClause() where, args := opts.WhereClause()
result, err := s.pp.GetPkgs(ctx, where, args...) packages, err := s.pp.GetPkgs(ctx, where, args...)
if err != nil { return packages, err
return nil, err
}
for result.Next() {
var dbPkg database.Package
err = result.StructScan(&dbPkg)
if err != nil {
return nil, err
}
packages = append(packages, dbPkg)
}
return packages, nil
} }

View File

@@ -22,6 +22,8 @@ package decoder
import ( import (
"context" "context"
"errors" "errors"
"fmt"
"log/slog"
"reflect" "reflect"
"strings" "strings"
@@ -31,8 +33,8 @@ import (
"mvdan.cc/sh/v3/interp" "mvdan.cc/sh/v3/interp"
"mvdan.cc/sh/v3/syntax" "mvdan.cc/sh/v3/syntax"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/overrides" "gitea.plemya-x.ru/Plemya-x/ALR/internal/overrides"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
) )
var ErrNotPointerToStruct = errors.New("val must be a pointer to a struct") var ErrNotPointerToStruct = errors.New("val must be a pointer to a struct")
@@ -52,7 +54,7 @@ type InvalidTypeError struct {
} }
func (ite InvalidTypeError) Error() string { func (ite InvalidTypeError) Error() string {
return "variable '" + ite.name + "' is of type " + ite.vartype + ", but " + ite.exptype + " is expected" return fmt.Sprintf("variable '%s' is of type %s, but %s is expected", ite.name, ite.vartype, ite.exptype)
} }
// Decoder provides methods for decoding variable values // Decoder provides methods for decoding variable values
@@ -81,13 +83,48 @@ func (d *Decoder) DecodeVar(name string, val any) error {
dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
WeaklyTypedInput: true, WeaklyTypedInput: true,
DecodeHook: mapstructure.DecodeHookFuncValue(func(from, to reflect.Value) (interface{}, error) { DecodeHook: mapstructure.DecodeHookFuncValue(func(from, to reflect.Value) (interface{}, error) {
if strings.Contains(to.Type().String(), "db.JSON") { if strings.Contains(to.Type().String(), "alrsh.OverridableField") {
valType := to.FieldByName("Val").Type() if to.Kind() != reflect.Ptr && to.CanAddr() {
if !from.Type().AssignableTo(valType) { to = to.Addr()
return nil, InvalidTypeError{name, from.Type().String(), valType.String()} }
names, err := overrides.Resolve(d.info, overrides.DefaultOpts.WithName(name))
if err != nil {
return nil, err
}
isNotSet := true
setMethod := to.MethodByName("Set")
setResolvedMethod := to.MethodByName("SetResolved")
for _, varName := range names {
val := d.getVarNoOverrides(varName)
if val == nil {
continue
}
t := setMethod.Type().In(1)
newVal := from
if !newVal.Type().AssignableTo(t) {
newVal = reflect.New(t)
err = d.DecodeVar(name, newVal.Interface())
if err != nil {
return nil, err
}
newVal = newVal.Elem()
}
if isNotSet {
setResolvedMethod.Call([]reflect.Value{newVal})
}
override := strings.TrimPrefix(strings.TrimPrefix(varName, name), "_")
setMethod.Call([]reflect.Value{reflect.ValueOf(override), newVal})
} }
to.FieldByName("Val").Set(from)
return to, nil return to, nil
} }
return from.Interface(), nil return from.Interface(), nil
@@ -96,6 +133,7 @@ func (d *Decoder) DecodeVar(name string, val any) error {
TagName: "sh", TagName: "sh",
}) })
if err != nil { if err != nil {
slog.Warn("err", "err", err)
return err return err
} }
@@ -255,7 +293,16 @@ func (d *Decoder) getVar(name string) *expand.Variable {
} }
for _, varName := range names { for _, varName := range names {
val, ok := d.Runner.Vars[varName] res := d.getVarNoOverrides(varName)
if res != nil {
return res
}
}
return nil
}
func (d *Decoder) getVarNoOverrides(name string) *expand.Variable {
val, ok := d.Runner.Vars[name]
if ok { if ok {
// Resolve nameref variables // Resolve nameref variables
_, resolved := val.Resolve(expand.FuncEnviron(func(s string) string { _, resolved := val.Resolve(expand.FuncEnviron(func(s string) string {
@@ -268,7 +315,6 @@ func (d *Decoder) getVar(name string) *expand.Variable {
return &val return &val
} }
}
return nil return nil
} }

View File

@@ -31,8 +31,8 @@ import (
"mvdan.cc/sh/v3/interp" "mvdan.cc/sh/v3/interp"
"mvdan.cc/sh/v3/syntax" "mvdan.cc/sh/v3/syntax"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/decoder" "gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/decoder"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
) )
type BuildVars struct { type BuildVars struct {

View File

@@ -27,9 +27,9 @@ import (
"mvdan.cc/sh/v3/interp" "mvdan.cc/sh/v3/interp"
"mvdan.cc/sh/v3/syntax" "mvdan.cc/sh/v3/syntax"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/decoder" "gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/decoder"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/handlers" "gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/handlers"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
) )
const testScript = ` const testScript = `

View File

@@ -126,71 +126,67 @@ msgstr ""
msgid "Error getting packages" msgid "Error getting packages"
msgstr "" msgstr ""
#: info.go:76 #: info.go:83
msgid "Error iterating over packages"
msgstr ""
#: info.go:90
msgid "Command info expected at least 1 argument, got %d" msgid "Command info expected at least 1 argument, got %d"
msgstr "" msgstr ""
#: info.go:110 #: info.go:104
msgid "Error finding packages" msgid "Error finding packages"
msgstr "" msgstr ""
#: info.go:124 #: info.go:118
msgid "Can't detect system language" msgid "Can't detect system language"
msgstr "" msgstr ""
#: info.go:141 #: info.go:135
msgid "Error resolving overrides" msgid "Error resolving overrides"
msgstr "" msgstr ""
#: info.go:149 info.go:154 #: info.go:144 info.go:149
msgid "Error encoding script variables" msgid "Error encoding script variables"
msgstr "" msgstr ""
#: install.go:40 #: install.go:39
msgid "Install a new package" msgid "Install a new package"
msgstr "" msgstr ""
#: install.go:52 #: install.go:51
msgid "Command install expected at least 1 argument, got %d" msgid "Command install expected at least 1 argument, got %d"
msgstr "" msgstr ""
#: install.go:114 #: install.go:113
msgid "Error when installing the package" msgid "Error when installing the package"
msgstr "" msgstr ""
#: install.go:159 #: install.go:151
msgid "Remove an installed package" msgid "Remove an installed package"
msgstr "" msgstr ""
#: install.go:178 #: install.go:170
msgid "Error listing installed packages" msgid "Error listing installed packages"
msgstr "" msgstr ""
#: install.go:215 #: install.go:199
msgid "Command remove expected at least 1 argument, got %d" msgid "Command remove expected at least 1 argument, got %d"
msgstr "" msgstr ""
#: install.go:230 #: install.go:214
msgid "Error removing packages" msgid "Error removing packages"
msgstr "" msgstr ""
#: internal/build/build.go:417 #: internal/build/build.go:376
msgid "Building package" msgid "Building package"
msgstr "" msgstr ""
#: internal/build/build.go:446 #: internal/build/build.go:405
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:488 #: internal/build/build.go:447
msgid "Downloading sources" msgid "Downloading sources"
msgstr "" msgstr ""
#: internal/build/build.go:580 #: internal/build/build.go:539
msgid "Installing dependencies" msgid "Installing dependencies"
msgstr "" msgstr ""
@@ -224,19 +220,19 @@ msgstr ""
msgid "AutoReq is not implemented for this package format, so it's skipped" msgid "AutoReq is not implemented for this package format, so it's skipped"
msgstr "" msgstr ""
#: internal/build/script_executor.go:236 #: internal/build/script_executor.go:145
msgid "Building package metadata" msgid "Building package metadata"
msgstr "" msgstr ""
#: internal/build/script_executor.go:366 #: internal/build/script_executor.go:276
msgid "Executing prepare()" msgid "Executing prepare()"
msgstr "" msgstr ""
#: internal/build/script_executor.go:375 #: internal/build/script_executor.go:285
msgid "Executing build()" msgid "Executing build()"
msgstr "" msgstr ""
#: internal/build/script_executor.go:404 internal/build/script_executor.go:424 #: internal/build/script_executor.go:314 internal/build/script_executor.go:334
msgid "Executing %s()" msgid "Executing %s()"
msgstr "" msgstr ""
@@ -248,15 +244,15 @@ msgstr ""
msgid "Error initialization database" msgid "Error initialization database"
msgstr "" msgstr ""
#: internal/cliutils/app_builder/builder.go:135 #: internal/cliutils/app_builder/builder.go:142
msgid "Error pulling repositories" msgid "Error pulling repositories"
msgstr "" msgstr ""
#: internal/cliutils/app_builder/builder.go:152 #: internal/cliutils/app_builder/builder.go:159
msgid "Error parsing os release" msgid "Error parsing os release"
msgstr "" msgstr ""
#: internal/cliutils/app_builder/builder.go:165 #: internal/cliutils/app_builder/builder.go:172
msgid "Unable to detect a supported package manager on the system" msgid "Unable to detect a supported package manager on the system"
msgstr "" msgstr ""
@@ -340,17 +336,17 @@ msgstr ""
msgid "OPTIONS" msgid "OPTIONS"
msgstr "" msgstr ""
#: internal/cliutils/utils.go:69 #: internal/cliutils/utils.go:72
msgid "" msgid ""
"This command is deprecated and would be removed in the future, use \"%s\" " "This command is deprecated and would be removed in the future, use \"%s\" "
"instead!" "instead!"
msgstr "" msgstr ""
#: internal/db/db.go:137 #: internal/db/db.go:76
msgid "Database version mismatch; resetting" msgid "Database version mismatch; resetting"
msgstr "" msgstr ""
#: internal/db/db.go:144 #: internal/db/db.go:82
msgid "" msgid ""
"Database version does not exist. Run alr fix if something isn't working." "Database version does not exist. Run alr fix if something isn't working."
msgstr "" msgstr ""
@@ -429,11 +425,11 @@ msgstr ""
msgid "No packages for upgrade" msgid "No packages for upgrade"
msgstr "" msgstr ""
#: list.go:102 list.go:187 #: list.go:102 list.go:184
msgid "Error parsing format template" msgid "Error parsing format template"
msgstr "" msgstr ""
#: list.go:108 list.go:191 #: list.go:108 list.go:188
msgid "Error executing template" msgid "Error executing template"
msgstr "" msgstr ""
@@ -545,14 +541,14 @@ msgstr ""
msgid "Error while executing search" msgid "Error while executing search"
msgstr "" msgstr ""
#: upgrade.go:47 #: upgrade.go:48
msgid "Upgrade all installed packages" msgid "Upgrade all installed packages"
msgstr "" msgstr ""
#: upgrade.go:105 upgrade.go:122 #: upgrade.go:106 upgrade.go:123
msgid "Error checking for updates" msgid "Error checking for updates"
msgstr "" msgstr ""
#: upgrade.go:125 #: upgrade.go:126
msgid "There is nothing to do." msgid "There is nothing to do."
msgstr "" msgstr ""

View File

@@ -133,71 +133,67 @@ msgstr "Показывать всю информацию, не только дл
msgid "Error getting packages" msgid "Error getting packages"
msgstr "Ошибка при получении пакетов" msgstr "Ошибка при получении пакетов"
#: info.go:76 #: info.go:83
msgid "Error iterating over packages"
msgstr "Ошибка при переборе пакетов"
#: info.go:90
msgid "Command info expected at least 1 argument, got %d" msgid "Command info expected at least 1 argument, got %d"
msgstr "Для команды info ожидался хотя бы 1 аргумент, получено %d" msgstr "Для команды info ожидался хотя бы 1 аргумент, получено %d"
#: info.go:110 #: info.go:104
msgid "Error finding packages" msgid "Error finding packages"
msgstr "Ошибка при поиске пакетов" msgstr "Ошибка при поиске пакетов"
#: info.go:124 #: info.go:118
msgid "Can't detect system language" msgid "Can't detect system language"
msgstr "Ошибка при определении языка системы" msgstr "Ошибка при определении языка системы"
#: info.go:141 #: info.go:135
msgid "Error resolving overrides" msgid "Error resolving overrides"
msgstr "Ошибка устранения переорпеделений" msgstr "Ошибка устранения переорпеделений"
#: info.go:149 info.go:154 #: info.go:144 info.go:149
msgid "Error encoding script variables" msgid "Error encoding script variables"
msgstr "Ошибка кодирования переменных скрита" msgstr "Ошибка кодирования переменных скрита"
#: install.go:40 #: install.go:39
msgid "Install a new package" msgid "Install a new package"
msgstr "Установить новый пакет" msgstr "Установить новый пакет"
#: install.go:52 #: install.go:51
msgid "Command install expected at least 1 argument, got %d" msgid "Command install expected at least 1 argument, got %d"
msgstr "Для команды install ожидался хотя бы 1 аргумент, получено %d" msgstr "Для команды install ожидался хотя бы 1 аргумент, получено %d"
#: install.go:114 #: install.go:113
msgid "Error when installing the package" msgid "Error when installing the package"
msgstr "Ошибка при установке пакета" msgstr "Ошибка при установке пакета"
#: install.go:159 #: install.go:151
msgid "Remove an installed package" msgid "Remove an installed package"
msgstr "Удалить установленный пакет" msgstr "Удалить установленный пакет"
#: install.go:178 #: install.go:170
msgid "Error listing installed packages" msgid "Error listing installed packages"
msgstr "Ошибка при составлении списка установленных пакетов" msgstr "Ошибка при составлении списка установленных пакетов"
#: install.go:215 #: install.go:199
msgid "Command remove expected at least 1 argument, got %d" msgid "Command remove expected at least 1 argument, got %d"
msgstr "Для команды remove ожидался хотя бы 1 аргумент, получено %d" msgstr "Для команды remove ожидался хотя бы 1 аргумент, получено %d"
#: install.go:230 #: install.go:214
msgid "Error removing packages" msgid "Error removing packages"
msgstr "Ошибка при удалении пакетов" msgstr "Ошибка при удалении пакетов"
#: internal/build/build.go:417 #: internal/build/build.go:376
msgid "Building package" msgid "Building package"
msgstr "Сборка пакета" msgstr "Сборка пакета"
#: internal/build/build.go:446 #: internal/build/build.go:405
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:488 #: internal/build/build.go:447
msgid "Downloading sources" msgid "Downloading sources"
msgstr "Скачивание источников" msgstr "Скачивание источников"
#: internal/build/build.go:580 #: internal/build/build.go:539
msgid "Installing dependencies" msgid "Installing dependencies"
msgstr "Установка зависимостей" msgstr "Установка зависимостей"
@@ -235,19 +231,19 @@ msgid "AutoReq is not implemented for this package format, so it's skipped"
msgstr "" msgstr ""
"AutoReq не реализовано для этого формата пакета, поэтому будет пропущено" "AutoReq не реализовано для этого формата пакета, поэтому будет пропущено"
#: internal/build/script_executor.go:236 #: internal/build/script_executor.go:145
msgid "Building package metadata" msgid "Building package metadata"
msgstr "Сборка метаданных пакета" msgstr "Сборка метаданных пакета"
#: internal/build/script_executor.go:366 #: internal/build/script_executor.go:276
msgid "Executing prepare()" msgid "Executing prepare()"
msgstr "Выполнение prepare()" msgstr "Выполнение prepare()"
#: internal/build/script_executor.go:375 #: internal/build/script_executor.go:285
msgid "Executing build()" msgid "Executing build()"
msgstr "Выполнение build()" msgstr "Выполнение build()"
#: internal/build/script_executor.go:404 internal/build/script_executor.go:424 #: internal/build/script_executor.go:314 internal/build/script_executor.go:334
msgid "Executing %s()" msgid "Executing %s()"
msgstr "Выполнение %s()" msgstr "Выполнение %s()"
@@ -259,15 +255,15 @@ msgstr "Ошибка при загрузке"
msgid "Error initialization database" msgid "Error initialization database"
msgstr "Ошибка инициализации базы данных" msgstr "Ошибка инициализации базы данных"
#: internal/cliutils/app_builder/builder.go:135 #: internal/cliutils/app_builder/builder.go:142
msgid "Error pulling repositories" msgid "Error pulling repositories"
msgstr "Ошибка при извлечении репозиториев" msgstr "Ошибка при извлечении репозиториев"
#: internal/cliutils/app_builder/builder.go:152 #: internal/cliutils/app_builder/builder.go:159
msgid "Error parsing os release" msgid "Error parsing os release"
msgstr "Ошибка при разборе файла выпуска операционной системы" msgstr "Ошибка при разборе файла выпуска операционной системы"
#: internal/cliutils/app_builder/builder.go:165 #: internal/cliutils/app_builder/builder.go:172
msgid "Unable to detect a supported package manager on the system" msgid "Unable to detect a supported package manager on the system"
msgstr "Не удалось обнаружить поддерживаемый менеджер пакетов в системе" msgstr "Не удалось обнаружить поддерживаемый менеджер пакетов в системе"
@@ -351,7 +347,7 @@ msgstr "КАТЕГОРИЯ"
msgid "OPTIONS" msgid "OPTIONS"
msgstr "ПАРАМЕТРЫ" msgstr "ПАРАМЕТРЫ"
#: internal/cliutils/utils.go:69 #: internal/cliutils/utils.go:72
msgid "" msgid ""
"This command is deprecated and would be removed in the future, use \"%s\" " "This command is deprecated and would be removed in the future, use \"%s\" "
"instead!" "instead!"
@@ -359,11 +355,11 @@ msgstr ""
"Эта команда устарела и будет удалена в будущем, используйте вместо нее \"%s" "Эта команда устарела и будет удалена в будущем, используйте вместо нее \"%s"
"\"!" "\"!"
#: internal/db/db.go:137 #: internal/db/db.go:76
msgid "Database version mismatch; resetting" msgid "Database version mismatch; resetting"
msgstr "Несоответствие версий базы данных; сброс настроек" msgstr "Несоответствие версий базы данных; сброс настроек"
#: internal/db/db.go:144 #: internal/db/db.go:82
msgid "" msgid ""
"Database version does not exist. Run alr fix if something isn't working." "Database version does not exist. Run alr fix if something isn't working."
msgstr "" msgstr ""
@@ -445,11 +441,11 @@ msgstr "Ошибка при получении пакетов для обнов
msgid "No packages for upgrade" msgid "No packages for upgrade"
msgstr "Нет пакетов к обновлению" msgstr "Нет пакетов к обновлению"
#: list.go:102 list.go:187 #: list.go:102 list.go:184
msgid "Error parsing format template" msgid "Error parsing format template"
msgstr "Ошибка при разборе шаблона" msgstr "Ошибка при разборе шаблона"
#: list.go:108 list.go:191 #: list.go:108 list.go:188
msgid "Error executing template" msgid "Error executing template"
msgstr "Ошибка при выполнении шаблона" msgstr "Ошибка при выполнении шаблона"
@@ -561,18 +557,21 @@ msgstr "Иcкать по provides"
msgid "Error while executing search" msgid "Error while executing search"
msgstr "Ошибка при выполнении поиска" msgstr "Ошибка при выполнении поиска"
#: upgrade.go:47 #: upgrade.go:48
msgid "Upgrade all installed packages" msgid "Upgrade all installed packages"
msgstr "Обновить все установленные пакеты" msgstr "Обновить все установленные пакеты"
#: upgrade.go:105 upgrade.go:122 #: upgrade.go:106 upgrade.go:123
msgid "Error checking for updates" msgid "Error checking for updates"
msgstr "Ошибка при проверке обновлений" msgstr "Ошибка при проверке обновлений"
#: upgrade.go:125 #: upgrade.go:126
msgid "There is nothing to do." msgid "There is nothing to do."
msgstr "Здесь нечего делать." msgstr "Здесь нечего делать."
#~ msgid "Error iterating over packages"
#~ msgstr "Ошибка при переборе пакетов"
#~ msgid "Error pulling repos" #~ msgid "Error pulling repos"
#~ msgstr "Ошибка при извлечении репозиториев" #~ msgstr "Ошибка при извлечении репозиториев"

11
list.go
View File

@@ -32,9 +32,9 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/build" "gitea.plemya-x.ru/Plemya-x/ALR/internal/build"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils" "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
appbuilder "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils/app_builder" appbuilder "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils/app_builder"
database "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/manager" "gitea.plemya-x.ru/Plemya-x/ALR/internal/manager"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/utils" "gitea.plemya-x.ru/Plemya-x/ALR/internal/utils"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
) )
func ListCmd() *cli.Command { func ListCmd() *cli.Command {
@@ -69,9 +69,9 @@ func ListCmd() *cli.Command {
WithConfig(). WithConfig().
WithDB(). WithDB().
WithManager(). WithManager().
WithDistroInfo().
// autoPull only // autoPull only
WithRepos(). WithRepos().
WithDistroInfo().
Build() Build()
if err != nil { if err != nil {
return err return err
@@ -125,7 +125,6 @@ func ListCmd() *cli.Command {
if err != nil { if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error getting packages"), err) return cliutils.FormatCliExit(gotext.Get("Error getting packages"), err)
} }
defer result.Close()
installedAlrPackages := map[string]string{} installedAlrPackages := map[string]string{}
if c.Bool("installed") { if c.Bool("installed") {
@@ -150,9 +149,7 @@ func ListCmd() *cli.Command {
} }
} }
for result.Next() { for _, pkg := range result {
var pkg database.Package
err := result.StructScan(&pkg)
if err != nil { if err != nil {
return cli.Exit(err, 1) return cli.Exit(err, 1)
} }
@@ -162,7 +159,7 @@ func ListCmd() *cli.Command {
} }
type packageInfo struct { type packageInfo struct {
Package *database.Package Package *alrsh.Package
Version string Version string
} }

View File

@@ -52,9 +52,9 @@
./internal/translations/files/lure.en.toml ./internal/translations/files/lure.en.toml
./internal/translations/files/lure.ru.toml ./internal/translations/files/lure.ru.toml
./internal/translations/translations.go ./internal/translations/translations.go
./internal/types/build.go ./pkg/types/build.go
./internal/types/config.go ./pkg/types/config.go
./internal/types/repo.go ./pkg/types/repo.go
./list.go ./list.go
./main.go ./main.go
./pkg/build/build.go ./pkg/build/build.go

205
pkg/alrsh/alrsh.go Normal file
View File

@@ -0,0 +1,205 @@
// 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 alrsh
import (
"context"
"errors"
"fmt"
"os"
"path/filepath"
"runtime"
"strconv"
"strings"
"mvdan.cc/sh/v3/expand"
"mvdan.cc/sh/v3/interp"
"mvdan.cc/sh/v3/syntax"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cpu"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/decoder"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/handlers"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/helpers"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
)
type ScriptFile struct {
file *syntax.File
path string
}
func createBuildEnvVars(info *distro.OSRelease, dirs types.Directories) []string {
env := os.Environ()
env = append(
env,
"DISTRO_NAME="+info.Name,
"DISTRO_PRETTY_NAME="+info.PrettyName,
"DISTRO_ID="+info.ID,
"DISTRO_VERSION_ID="+info.VersionID,
"DISTRO_ID_LIKE="+strings.Join(info.Like, " "),
"ARCH="+cpu.Arch(),
"NCPU="+strconv.Itoa(runtime.NumCPU()),
)
if dirs.ScriptDir != "" {
env = append(env, "scriptdir="+dirs.ScriptDir)
}
if dirs.PkgDir != "" {
env = append(env, "pkgdir="+dirs.PkgDir)
}
if dirs.SrcDir != "" {
env = append(env, "srcdir="+dirs.SrcDir)
}
return env
}
func (s *ScriptFile) ParseBuildVars(ctx context.Context, info *distro.OSRelease, packages []string) (string, []*Package, error) {
runner, err := s.createRunner(info)
if err != nil {
return "", nil, err
}
if err := runScript(ctx, runner, s.file); err != nil {
return "", nil, err
}
dec := newDecoder(info, runner)
pkgNames, err := ParseNames(dec)
if err != nil {
return "", nil, err
}
if len(pkgNames.Names) == 0 {
return "", nil, errors.New("package name is missing")
}
targetPackages := packages
if len(targetPackages) == 0 {
targetPackages = pkgNames.Names
}
varsOfPackages, err := s.createPackagesForBuildVars(ctx, dec, pkgNames, targetPackages)
if err != nil {
return "", nil, err
}
baseName := pkgNames.BasePkgName
if len(pkgNames.Names) == 1 {
baseName = pkgNames.Names[0]
}
return baseName, varsOfPackages, nil
}
func (s *ScriptFile) createRunner(info *distro.OSRelease) (*interp.Runner, error) {
scriptDir := filepath.Dir(s.path)
env := createBuildEnvVars(info, types.Directories{ScriptDir: scriptDir})
return interp.New(
interp.Env(expand.ListEnviron(env...)),
interp.StdIO(os.Stdin, os.Stderr, os.Stderr),
interp.ExecHandler(helpers.Restricted.ExecHandler(handlers.NopExec)),
interp.ReadDirHandler2(handlers.RestrictedReadDir(scriptDir)),
interp.StatHandler(handlers.RestrictedStat(scriptDir)),
interp.OpenHandler(handlers.RestrictedOpen(scriptDir)),
interp.Dir(scriptDir),
)
}
func (s *ScriptFile) createPackagesForBuildVars(
ctx context.Context,
dec *decoder.Decoder,
pkgNames *PackageNames,
targetPackages []string,
) ([]*Package, error) {
var varsOfPackages []*Package
if len(pkgNames.Names) == 1 {
var pkg Package
pkg.Name = pkgNames.Names[0]
if err := dec.DecodeVars(&pkg); err != nil {
return nil, err
}
varsOfPackages = append(varsOfPackages, &pkg)
return varsOfPackages, nil
}
for _, pkgName := range targetPackages {
pkg, err := s.createPackageFromMeta(ctx, dec, pkgName, pkgNames.BasePkgName)
if err != nil {
return nil, err
}
varsOfPackages = append(varsOfPackages, pkg)
}
return varsOfPackages, nil
}
func (s *ScriptFile) createPackageFromMeta(
ctx context.Context,
dec *decoder.Decoder,
pkgName, basePkgName string,
) (*Package, error) {
funcName := fmt.Sprintf("meta_%s", pkgName)
meta, ok := dec.GetFuncWithSubshell(funcName)
if !ok {
return nil, fmt.Errorf("func %s is missing", funcName)
}
metaRunner, err := meta(ctx)
if err != nil {
return nil, err
}
metaDecoder := decoder.New(&distro.OSRelease{}, metaRunner)
var vars Package
if err := metaDecoder.DecodeVars(&vars); err != nil {
return nil, err
}
vars.Name = pkgName
vars.BasePkgName = basePkgName
return &vars, nil
}
func runScript(ctx context.Context, runner *interp.Runner, fl *syntax.File) error {
runner.Reset()
return runner.Run(ctx, fl)
}
func newDecoder(info *distro.OSRelease, runner *interp.Runner) *decoder.Decoder {
d := decoder.New(info, runner)
// d.Overrides = false
// d.LikeDistros = false
return d
}
func (a *ScriptFile) Path() string {
return a.path
}
func (a *ScriptFile) File() *syntax.File {
return a.file
}

61
pkg/alrsh/gob.go Normal file
View File

@@ -0,0 +1,61 @@
// 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 alrsh
import (
"bytes"
"encoding/gob"
"mvdan.cc/sh/v3/syntax"
"mvdan.cc/sh/v3/syntax/typedjson"
)
func (s *ScriptFile) GobEncode() ([]byte, error) {
var buf bytes.Buffer
enc := gob.NewEncoder(&buf)
if err := enc.Encode(s.path); err != nil {
return nil, err
}
var fileBuf bytes.Buffer
if err := typedjson.Encode(&fileBuf, s.file); err != nil {
return nil, err
}
fileData := fileBuf.Bytes()
if err := enc.Encode(fileData); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func (s *ScriptFile) GobDecode(data []byte) error {
buf := bytes.NewBuffer(data)
dec := gob.NewDecoder(buf)
if err := dec.Decode(&s.path); err != nil {
return err
}
var fileData []byte
if err := dec.Decode(&fileData); err != nil {
return err
}
fileReader := bytes.NewReader(fileData)
file, err := typedjson.Decode(fileReader)
if err != nil {
return err
}
s.file = file.(*syntax.File)
return nil
}

146
pkg/alrsh/overridable.go Normal file
View File

@@ -0,0 +1,146 @@
// 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 alrsh
import (
"bytes"
"encoding/gob"
"encoding/json"
)
type OverridableField[T any] struct {
data map[string]T
// It can't be a pointer
//
// See https://gitea.com/xorm/xorm/issues/2431
resolved T
}
func (f *OverridableField[T]) Set(key string, value T) {
if f.data == nil {
f.data = make(map[string]T)
}
f.data[key] = value
}
func (f *OverridableField[T]) Get(key string) T {
if f.data == nil {
f.data = make(map[string]T)
}
return f.data[key]
}
func (f *OverridableField[T]) Has(key string) (T, bool) {
if f.data == nil {
f.data = make(map[string]T)
}
val, ok := f.data[key]
return val, ok
}
func (f *OverridableField[T]) SetResolved(value T) {
f.resolved = value
}
func (f *OverridableField[T]) Resolved() T {
return f.resolved
}
func (f *OverridableField[T]) All() map[string]T {
return f.data
}
func (o *OverridableField[T]) Resolve(overrides []string) {
for _, override := range overrides {
if v, ok := o.Has(override); ok {
o.SetResolved(v)
}
}
}
func (f *OverridableField[T]) ToDB() ([]byte, error) {
var data map[string]T
if f.data == nil {
data = make(map[string]T)
} else {
data = f.data
}
return json.Marshal(data)
}
func (f *OverridableField[T]) FromDB(data []byte) error {
if len(data) == 0 {
*f = OverridableField[T]{data: make(map[string]T)}
return nil
}
var temp map[string]T
if err := json.Unmarshal(data, &temp); err != nil {
return err
}
if temp == nil {
temp = make(map[string]T)
}
*f = OverridableField[T]{data: temp}
return nil
}
type overridableFieldGobPayload[T any] struct {
Data map[string]T
Resolved T
}
func (f *OverridableField[T]) GobEncode() ([]byte, error) {
var buf bytes.Buffer
enc := gob.NewEncoder(&buf)
payload := overridableFieldGobPayload[T]{
Data: f.data,
Resolved: f.resolved,
}
if err := enc.Encode(payload); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func (f *OverridableField[T]) GobDecode(data []byte) error {
dec := gob.NewDecoder(bytes.NewBuffer(data))
var payload overridableFieldGobPayload[T]
if err := dec.Decode(&payload); err != nil {
return err
}
f.data = payload.Data
f.resolved = payload.Resolved
return nil
}
func OverridableFromMap[T any](data map[string]T) OverridableField[T] {
if data == nil {
data = make(map[string]T)
}
return OverridableField[T]{
data: data,
}
}

105
pkg/alrsh/package.go Normal file
View File

@@ -0,0 +1,105 @@
// 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 alrsh
import (
"fmt"
"reflect"
"strings"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/decoder"
)
type PackageNames struct {
BasePkgName string `sh:"basepkg_name"`
Names []string `sh:"name"`
}
func ParseNames(dec *decoder.Decoder) (*PackageNames, error) {
var pkgs PackageNames
err := dec.DecodeVars(&pkgs)
if err != nil {
return nil, fmt.Errorf("fail parse names: %w", err)
}
return &pkgs, nil
}
type Package struct {
Repository string `xorm:"pk 'repository'"`
Name string `xorm:"pk 'name'"`
BasePkgName string `xorm:"notnull 'basepkg_name'"`
Version string `sh:"version" xorm:"notnull 'version'"`
Release int `sh:"release" xorm:"notnull 'release'"`
Epoch uint `sh:"epoch" xorm:"'epoch'"`
Architectures []string `sh:"architectures" xorm:"json 'architectures'"`
Licenses []string `sh:"license" xorm:"json 'licenses'"`
Provides []string `sh:"provides" xorm:"json 'provides'"`
Conflicts []string `sh:"conflicts" xorm:"json 'conflicts'"`
Replaces []string `sh:"replaces" xorm:"json 'replaces'"`
Summary OverridableField[string] `sh:"summary" xorm:"'summary'"`
Description OverridableField[string] `sh:"desc" xorm:"'description'"`
Group OverridableField[string] `sh:"group" xorm:"'group_name'"`
Homepage OverridableField[string] `sh:"homepage" xorm:"'homepage'"`
Maintainer OverridableField[string] `sh:"maintainer" xorm:"'maintainer'"`
Depends OverridableField[[]string] `sh:"deps" xorm:"'depends'"`
BuildDepends OverridableField[[]string] `sh:"build_deps" xorm:"'builddepends'"`
OptDepends OverridableField[[]string] `sh:"opt_deps" xorm:"'optdepends'"`
Sources OverridableField[[]string] `sh:"sources" xorm:"-"`
Checksums OverridableField[[]string] `sh:"checksums" xorm:"-"`
Backup OverridableField[[]string] `sh:"backup" xorm:"-"`
Scripts OverridableField[Scripts] `sh:"scripts" xorm:"-"`
AutoReq OverridableField[[]string] `sh:"auto_req" xorm:"-"`
AutoProv OverridableField[[]string] `sh:"auto_prov" xorm:"-"`
AutoReqSkipList OverridableField[[]string] `sh:"auto_req_skiplist" xorm:"-"`
AutoProvSkipList OverridableField[[]string] `sh:"auto_prov_skiplist" xorm:"-"`
}
type Scripts struct {
PreInstall string `sh:"preinstall"`
PostInstall string `sh:"postinstall"`
PreRemove string `sh:"preremove"`
PostRemove string `sh:"postremove"`
PreUpgrade string `sh:"preupgrade"`
PostUpgrade string `sh:"postupgrade"`
PreTrans string `sh:"pretrans"`
PostTrans string `sh:"posttrans"`
}
func ResolvePackage(p *Package, overrides []string) {
val := reflect.ValueOf(p).Elem()
typ := val.Type()
for i := range val.NumField() {
field := val.Field(i)
fieldType := typ.Field(i)
if !field.CanInterface() {
continue
}
if field.Kind() == reflect.Struct && strings.HasPrefix(fieldType.Type.String(), "alrsh.OverridableField") {
of := field.Addr().Interface()
if res, ok := of.(interface {
Resolve([]string)
}); ok {
res.Resolve(overrides)
}
}
}
}

57
pkg/alrsh/read.go Normal file
View File

@@ -0,0 +1,57 @@
// 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 alrsh
import (
"fmt"
"io"
"io/fs"
"os"
"mvdan.cc/sh/v3/syntax"
)
type localFs struct{}
func (fs *localFs) Open(name string) (fs.File, error) {
return os.Open(name)
}
func ReadFromIOReader(r io.Reader, script string) (*ScriptFile, error) {
file, err := syntax.NewParser().Parse(r, "alr.sh")
if err != nil {
return nil, err
}
return &ScriptFile{
file: file,
path: script,
}, nil
}
func ReadFromFS(fsys fs.FS, script string) (*ScriptFile, error) {
fl, err := fsys.Open(script)
if err != nil {
return nil, fmt.Errorf("failed to open alr.sh: %w", err)
}
defer fl.Close()
return ReadFromIOReader(fl, script)
}
func ReadFromLocal(script string) (*ScriptFile, error) {
return ReadFromFS(&localFs{}, script)
}

View File

@@ -24,49 +24,6 @@ type BuildOpts struct {
Interactive bool Interactive bool
} }
type BuildVarsPre struct {
Version string `sh:"version,required"`
Release int `sh:"release,required"`
Epoch uint `sh:"epoch"`
Summary string `sh:"summary"`
Description string `sh:"desc"`
Group string `sh:"group"`
Homepage string `sh:"homepage"`
Maintainer string `sh:"maintainer"`
Architectures []string `sh:"architectures"`
Licenses []string `sh:"license"`
Provides []string `sh:"provides"`
Conflicts []string `sh:"conflicts"`
Depends []string `sh:"deps"`
BuildDepends []string `sh:"build_deps"`
OptDepends []string `sh:"opt_deps"`
Replaces []string `sh:"replaces"`
Sources []string `sh:"sources"`
Checksums []string `sh:"checksums"`
Backup []string `sh:"backup"`
Scripts Scripts `sh:"scripts"`
AutoReq []string `sh:"auto_req"`
AutoProv []string `sh:"auto_prov"`
AutoReqSkipList []string `sh:"auto_req_skiplist"`
AutoProvSkipList []string `sh:"auto_prov_skiplist"`
}
func (bv *BuildVarsPre) ToBuildVars() BuildVars {
return BuildVars{
Name: "",
Base: "",
BuildVarsPre: *bv,
}
}
// BuildVars represents the script variables required
// to build a package
type BuildVars struct {
Name string `sh:"name,required"`
Base string
BuildVarsPre
}
type Scripts struct { type Scripts struct {
PreInstall string `sh:"preinstall"` PreInstall string `sh:"preinstall"`
PostInstall string `sh:"postinstall"` PostInstall string `sh:"postinstall"`

66
pkg/types/script.go Normal file
View File

@@ -0,0 +1,66 @@
// 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 types
import (
"bytes"
"encoding/gob"
"mvdan.cc/sh/v3/syntax"
"mvdan.cc/sh/v3/syntax/typedjson"
)
type ScriptFile struct {
File *syntax.File
Path string
}
func (s *ScriptFile) GobEncode() ([]byte, error) {
var buf bytes.Buffer
enc := gob.NewEncoder(&buf)
if err := enc.Encode(s.Path); err != nil {
return nil, err
}
var fileBuf bytes.Buffer
if err := typedjson.Encode(&fileBuf, s.File); err != nil {
return nil, err
}
fileData := fileBuf.Bytes()
if err := enc.Encode(fileData); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func (s *ScriptFile) GobDecode(data []byte) error {
buf := bytes.NewBuffer(data)
dec := gob.NewDecoder(buf)
if err := dec.Decode(&s.Path); err != nil {
return err
}
var fileData []byte
if err := dec.Decode(&fileData); err != nil {
return err
}
fileReader := bytes.NewReader(fileData)
file, err := typedjson.Decode(fileReader)
if err != nil {
return err
}
s.File = file.(*syntax.File)
return nil
}

View File

@@ -29,8 +29,8 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils" "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
appbuilder "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils/app_builder" appbuilder "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils/app_builder"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/utils" "gitea.plemya-x.ru/Plemya-x/ALR/internal/utils"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
) )
func RepoCmd() *cli.Command { func RepoCmd() *cli.Command {

View File

@@ -27,11 +27,11 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils" "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
appbuilder "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils/app_builder" appbuilder "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils/app_builder"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/overrides" "gitea.plemya-x.ru/Plemya-x/ALR/internal/overrides"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/search" "gitea.plemya-x.ru/Plemya-x/ALR/internal/search"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/utils" "gitea.plemya-x.ru/Plemya-x/ALR/internal/utils"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
) )
func SearchCmd() *cli.Command { func SearchCmd() *cli.Command {
@@ -139,27 +139,16 @@ func SearchCmd() *cli.Command {
} }
} }
for _, dbPkg := range packages { for _, pkg := range packages {
var pkg any alrsh.ResolvePackage(&pkg, names)
if !all {
pkg = overrides.ResolvePackage(&dbPkg, names)
} else {
pkg = &dbPkg
}
if tmpl != nil { if tmpl != nil {
err = tmpl.Execute(os.Stdout, pkg) err = tmpl.Execute(os.Stdout, &pkg)
if err != nil { if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error executing template"), err) return cliutils.FormatCliExit(gotext.Get("Error executing template"), err)
} }
fmt.Println() fmt.Println()
} else { } else {
switch v := pkg.(type) { fmt.Println(pkg.Name)
case *overrides.ResolvedPackage:
fmt.Println(v.Name)
case *db.Package:
fmt.Println(v.Name)
}
} }
} }

View File

@@ -33,12 +33,13 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils" "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
appbuilder "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils/app_builder" appbuilder "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils/app_builder"
database "gitea.plemya-x.ru/Plemya-x/ALR/internal/db" database "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/manager" "gitea.plemya-x.ru/Plemya-x/ALR/internal/manager"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/overrides" "gitea.plemya-x.ru/Plemya-x/ALR/internal/overrides"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/search" "gitea.plemya-x.ru/Plemya-x/ALR/internal/search"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/utils" "gitea.plemya-x.ru/Plemya-x/ALR/internal/utils"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
) )
func UpgradeCmd() *cli.Command { func UpgradeCmd() *cli.Command {
@@ -130,8 +131,8 @@ func UpgradeCmd() *cli.Command {
} }
} }
func mapUptatesInfoToPackages(updates []UpdateInfo) []database.Package { func mapUptatesInfoToPackages(updates []UpdateInfo) []alrsh.Package {
var pkgs []database.Package var pkgs []alrsh.Package
for _, info := range updates { for _, info := range updates {
pkgs = append(pkgs, *info.Package) pkgs = append(pkgs, *info.Package)
} }
@@ -139,7 +140,7 @@ func mapUptatesInfoToPackages(updates []UpdateInfo) []database.Package {
} }
type UpdateInfo struct { type UpdateInfo struct {
Package *database.Package Package *alrsh.Package
FromVersion string FromVersion string
ToVersion string ToVersion string