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">
<text x="33.5" y="15" fill="#010101" fill-opacity=".3">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="14">16.9%</text>
<text x="86" y="15" fill="#010101" fill-opacity=".3">17.6%</text>
<text x="86" y="14">17.6%</text>
</g>
</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"
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/types"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/utils"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
)
func BuildCmd() *cli.Command {

View File

@@ -31,8 +31,8 @@ func TestE2EGroupAndSummaryField(t *testing.T) {
RPM_SYSTEMS,
func(t *testing.T, r e2e.Runnable) {
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 \"{{.Summary}}\" | grep \"^Custom summary$\"")
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.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
github.com/AlecAivazis/survey/v2 v2.3.7
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/caarlos0/env v3.5.0+incompatible
github.com/charmbracelet/bubbles v0.20.0
@@ -42,6 +41,7 @@ require (
gopkg.in/yaml.v3 v3.0.1
modernc.org/sqlite v1.25.0
mvdan.cc/sh/v3 v3.10.0
xorm.io/xorm v1.3.9
)
require (
@@ -52,7 +52,6 @@ require (
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
github.com/Microsoft/go-winio v0.6.1 // 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/aymanbagabas/go-osc52/v2 v2.0.1 // 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-logfmt/logfmt v0.6.0 // 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/protobuf v1.5.3 // 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/go-multierror v1.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/imdario/mergo v0.3.16 // 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/kevinburke/ssh_config v1.2.0 // 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/mitchellh/copystructure v1.2.0 // 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/cancelreader v0.2.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/russross/blackfriday/v2 v2.1.0 // 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/spf13/cast v1.6.0 // indirect
github.com/syndtr/goleveldb v1.0.0 // indirect
github.com/therootcompany/xz v1.0.1 // indirect
github.com/ulikunitz/xz v0.5.12 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
@@ -145,4 +148,5 @@ require (
modernc.org/opt v0.1.3 // indirect
modernc.org/strutil v1.1.3 // 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/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
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/go.mod h1:iKQM6uttMJgE5CFrPw6SQqAV7TKtlJNICRAie/dTciw=
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/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
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/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=
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-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=
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.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/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/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=
@@ -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.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
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/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
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.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
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/go.mod h1:nOFQdrUlIlx6M6ODdSpBj1NVA+VgLC6kmw60mkw34H4=
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/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/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/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
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/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
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.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
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/leonelquinteros/gotext v1.7.0 h1:jcJmF4AXqyamP7vuw2MMIKs+O3jAEmvrc5JQiI8Ht/8=
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.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/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
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.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
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/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
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/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
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/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
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/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/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.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/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY=
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.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
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.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
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/go.mod h1:/roCdA6gg6lQyw/Oz6gIIGu3ggJKYhF+WC/AQReE5XQ=
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/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-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-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
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/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-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-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
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/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
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/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.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
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/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
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/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/pkg/distro"
)
func HelperCmd() *cli.Command {

17
info.go
View File

@@ -30,10 +30,10 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
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/utils"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
)
func InfoCmd() *cli.Command {
@@ -67,15 +67,8 @@ func InfoCmd() *cli.Command {
if err != nil {
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)
}
return nil
@@ -96,6 +89,7 @@ func InfoCmd() *cli.Command {
New(ctx).
WithConfig().
WithDB().
WithDistroInfo().
WithRepos().
Build()
if err != nil {
@@ -144,7 +138,8 @@ func InfoCmd() *cli.Command {
for _, pkg := range pkgs {
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 {
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/cliutils"
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/types"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/utils"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
)
func InstallCmd() *cli.Command {
@@ -136,15 +135,8 @@ func InstallCmd() *cli.Command {
if err != nil {
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)
}
@@ -190,20 +182,12 @@ func RemoveCmd() *cli.Command {
if err != nil {
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)]
if !ok {
continue
}
fmt.Println(pkg.Name)
}

View File

@@ -24,18 +24,17 @@ import (
"context"
"encoding/gob"
"errors"
"fmt"
"log/slog"
"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/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/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 {
@@ -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 {
Name string
Path string
@@ -200,7 +158,7 @@ func GetBuiltName(deps []*BuiltDep) []string {
}
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 {
@@ -215,12 +173,12 @@ type FunctionsOutput struct {
// EXECUTORS
type ScriptResolverExecutor interface {
ResolveScript(ctx context.Context, pkg *db.Package) *ScriptInfo
ResolveScript(ctx context.Context, pkg *alrsh.Package) *ScriptInfo
}
type ScriptExecutor interface {
ReadScript(ctx context.Context, scriptPath string) (*ScriptFile, error)
ExecuteFirstPass(ctx context.Context, input *BuildInput, sf *ScriptFile) (string, []*types.BuildVars, error)
ReadScript(ctx context.Context, scriptPath string) (*alrsh.ScriptFile, error)
ExecuteFirstPass(ctx context.Context, input *BuildInput, sf *alrsh.ScriptFile) (string, []*alrsh.Package, error)
PrepareDirs(
ctx context.Context,
input *BuildInput,
@@ -229,8 +187,8 @@ type ScriptExecutor interface {
ExecuteSecondPass(
ctx context.Context,
input *BuildInput,
sf *ScriptFile,
varsOfPackages []*types.BuildVars,
sf *alrsh.ScriptFile,
varsOfPackages []*alrsh.Package,
repoDeps []string,
builtDeps []*BuiltDep,
basePkg string,
@@ -238,18 +196,18 @@ type ScriptExecutor 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 {
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 {
PerformChecks(
ctx context.Context,
input *BuildInput,
vars *types.BuildVars,
vars *alrsh.Package,
) (bool, error)
}
@@ -327,7 +285,7 @@ func (b *BuildArgs) PkgFormat() string {
type BuildPackageFromDbArgs struct {
BuildArgs
Package *db.Package
Package *alrsh.Package
Packages []string
}
@@ -376,19 +334,19 @@ func (b *Builder) BuildPackage(
slog.Debug("ReadScript")
sf, err := b.scriptExecutor.ReadScript(ctx, scriptPath)
if err != nil {
return nil, err
return nil, fmt.Errorf("failed reading script: %w", err)
}
slog.Debug("ExecuteFirstPass")
basePkg, varsOfPackages, err := b.scriptExecutor.ExecuteFirstPass(ctx, input, sf)
if err != nil {
return nil, err
return nil, fmt.Errorf("failed ExecuteFirstPass: %w", err)
}
var builtDeps []*BuiltDep
if !input.opts.Clean {
var remainingVars []*types.BuildVars
var remainingVars []*alrsh.Package
for _, vars := range varsOfPackages {
builtPkgPath, ok, err := b.cacheExecutor.CheckForBuiltPackage(ctx, input, vars)
if err != nil {
@@ -409,6 +367,7 @@ func (b *Builder) BuildPackage(
}
slog.Debug("ViewScript")
slog.Debug("", "varsOfPackages", varsOfPackages)
err = b.scriptViewerExecutor.ViewScript(ctx, input, sf, basePkg)
if err != nil {
return nil, err
@@ -432,11 +391,11 @@ func (b *Builder) BuildPackage(
sources := []string{}
checksums := []string{}
for _, vars := range varsOfPackages {
buildDepends = append(buildDepends, vars.BuildDepends...)
optDepends = append(optDepends, vars.OptDepends...)
depends = append(depends, vars.Depends...)
sources = append(sources, vars.Sources...)
checksums = append(checksums, vars.Checksums...)
buildDepends = append(buildDepends, vars.BuildDepends.Resolved()...)
optDepends = append(optDepends, vars.OptDepends.Resolved()...)
depends = append(depends, vars.Depends.Resolved()...)
sources = append(sources, vars.Sources.Resolved()...)
checksums = append(checksums, vars.Checksums.Resolved()...)
}
buildDepends = removeDuplicates(buildDepends)
optDepends = removeDuplicates(optDepends)
@@ -523,7 +482,7 @@ func (b *Builder) BuildPackage(
type InstallPkgsArgs struct {
BuildArgs
AlrPkgs []db.Package
AlrPkgs []alrsh.Package
NativePkgs []string
}
@@ -534,7 +493,7 @@ func (b *Builder) InstallALRPackages(
BuildOptsProvider
PkgFormatProvider
},
alrPkgs []db.Package,
alrPkgs []alrsh.Package,
) error {
for _, pkg := range alrPkgs {
res, err := b.BuildPackageFromDb(
@@ -581,7 +540,7 @@ func (b *Builder) BuildALRDeps(
found, notFound, err := b.repos.FindPkgs(ctx, depends) // Поиск зависимостей
if err != nil {
return nil, nil, err
return nil, nil, fmt.Errorf("failed FindPkgs: %w", err)
}
repoDeps = notFound
@@ -593,7 +552,7 @@ func (b *Builder) BuildALRDeps(
input.BuildOpts().Interactive,
)
type item struct {
pkg *db.Package
pkg *alrsh.Package
packages []string
}
pkgsMap := make(map[string]*item)
@@ -628,7 +587,7 @@ func (b *Builder) BuildALRDeps(
},
)
if err != nil {
return nil, nil, err
return nil, nil, fmt.Errorf("failed build package from db: %w", err)
}
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/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/manager"
)

View File

@@ -23,7 +23,7 @@ import (
"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 {
@@ -33,7 +33,7 @@ type Cache struct {
func (c *Cache) CheckForBuiltPackage(
ctx context.Context,
input *BuildInput,
vars *types.BuildVars,
vars *alrsh.Package,
) (string, bool, error) {
filename, err := pkgFileName(input, vars)
if err != nil {
@@ -56,7 +56,7 @@ func pkgFileName(
PkgFormatProvider
RepositoryProvider
},
vars *types.BuildVars,
vars *alrsh.Package,
) (string, error) {
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/cpu"
"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 {
@@ -35,7 +35,7 @@ type Checker struct {
func (c *Checker) PerformChecks(
ctx context.Context,
input *BuildInput,
vars *types.BuildVars,
vars *alrsh.Package,
) (bool, error) {
if !cpu.IsCompatibleWith(cpu.Arch(), vars.Architectures) { // Проверяем совместимость архитектуры
cont, err := cliutils.YesNoPrompt(

View File

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

View File

@@ -27,7 +27,7 @@ import (
"github.com/goreleaser/nfpm/v2"
"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 {

View File

@@ -23,7 +23,7 @@ import (
"github.com/goreleaser/nfpm/v2"
"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{}

View File

@@ -28,7 +28,7 @@ import (
"github.com/goreleaser/nfpm/v2"
"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{}

View File

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

View File

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

View File

@@ -19,7 +19,6 @@ package build
import (
"bytes"
"context"
"errors"
"fmt"
"log/slog"
"os"
@@ -37,11 +36,11 @@ import (
"mvdan.cc/sh/v3/syntax"
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/handlers"
"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 {
@@ -54,102 +53,12 @@ func NewLocalScriptExecutor(cfg Config) *LocalScriptExecutor {
}
}
func (e *LocalScriptExecutor) ReadScript(ctx context.Context, scriptPath string) (*ScriptFile, error) {
fl, err := readScript(scriptPath)
if err != nil {
return nil, err
}
return &ScriptFile{
Path: scriptPath,
File: fl,
}, nil
func (e *LocalScriptExecutor) ReadScript(ctx context.Context, scriptPath string) (*alrsh.ScriptFile, error) {
return alrsh.ReadFromLocal(scriptPath)
}
func (e *LocalScriptExecutor) ExecuteFirstPass(ctx context.Context, input *BuildInput, sf *ScriptFile) (string, []*types.BuildVars, error) {
varsOfPackages := []*types.BuildVars{}
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) ExecuteFirstPass(ctx context.Context, input *BuildInput, sf *alrsh.ScriptFile) (string, []*alrsh.Package, error) {
return sf.ParseBuildVars(ctx, input.info, input.packages)
}
func (e *LocalScriptExecutor) PrepareDirs(
@@ -177,13 +86,13 @@ func (e *LocalScriptExecutor) PrepareDirs(
func (e *LocalScriptExecutor) ExecuteSecondPass(
ctx context.Context,
input *BuildInput,
sf *ScriptFile,
varsOfPackages []*types.BuildVars,
sf *alrsh.ScriptFile,
varsOfPackages []*alrsh.Package,
repoDeps []string,
builtDeps []*BuiltDep,
basePkg string,
) ([]*BuiltDep, error) {
dirs, err := getDirs(e.cfg, sf.Path, basePkg)
dirs, err := getDirs(e.cfg, sf.Path(), basePkg)
if err != nil {
return nil, err
}
@@ -201,7 +110,7 @@ func (e *LocalScriptExecutor) ExecuteSecondPass(
return nil, err
}
err = runner.Run(ctx, sf.File)
err = runner.Run(ctx, sf.File())
if err != nil {
return nil, err
}
@@ -217,7 +126,7 @@ func (e *LocalScriptExecutor) ExecuteSecondPass(
for _, vars := range varsOfPackages {
packageName := ""
if vars.Base != "" {
if vars.BasePkgName != "" {
packageName = vars.Name
}
@@ -285,24 +194,25 @@ func buildPkgMetadata(
PkgFormatProvider
RepositoryProvider
},
vars *types.BuildVars,
vars *alrsh.Package,
dirs types.Directories,
deps []string,
preferedContents *[]string,
) (*nfpm.Info, error) {
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.Homepage = vars.Homepage
pkgInfo.Homepage = vars.Homepage.Resolved()
pkgInfo.License = strings.Join(vars.Licenses, ", ")
pkgInfo.Maintainer = vars.Maintainer
pkgInfo.Maintainer = vars.Maintainer.Resolved()
pkgInfo.Overridables = nfpm.Overridables{
Conflicts: append(vars.Conflicts, vars.Name),
Replaces: vars.Replaces,
Provides: append(vars.Provides, vars.Name),
Depends: deps,
}
pkgInfo.Section = vars.Group
pkgInfo.Section = vars.Group.Resolved()
pkgFormat := input.PkgFormat()
info := input.OSRelease()
@@ -315,12 +225,12 @@ func buildPkgMetadata(
}
if pkgFormat == "rpm" {
pkgInfo.RPM.Group = vars.Group
pkgInfo.RPM.Group = vars.Group.Resolved()
if vars.Summary != "" {
pkgInfo.RPM.Summary = vars.Summary
if vars.Summary.Resolved() != "" {
pkgInfo.RPM.Summary = vars.Summary.Resolved()
} else {
lines := strings.SplitN(vars.Description, "\n", 2)
lines := strings.SplitN(vars.Description.Resolved(), "\n", 2)
pkgInfo.RPM.Summary = lines[0]
}
}
@@ -341,17 +251,17 @@ func buildPkgMetadata(
}
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)
err = f.FindProvides(ctx, pkgInfo, dirs, vars.AutoProvSkipList)
err = f.FindProvides(ctx, pkgInfo, dirs, vars.AutoProvSkipList.Resolved())
if err != nil {
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)
err = f.FindRequires(ctx, pkgInfo, dirs, vars.AutoReqSkipList)
err = f.FindRequires(ctx, pkgInfo, dirs, vars.AutoReqSkipList.Resolved())
if err != nil {
return nil, err
}

View File

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

View File

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

View File

@@ -33,34 +33,18 @@ import (
_ "github.com/goreleaser/nfpm/v2/arch"
_ "github.com/goreleaser/nfpm/v2/deb"
_ "github.com/goreleaser/nfpm/v2/rpm"
"mvdan.cc/sh/v3/syntax"
"github.com/goreleaser/nfpm/v2"
"github.com/goreleaser/nfpm/v2/files"
"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/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 подготавливает директории для сборки.
func prepareDirs(dirs types.Directories) error {
err := os.RemoveAll(dirs.BaseDir) // Удаляем базовую директорию, если она существует
@@ -76,7 +60,7 @@ func prepareDirs(dirs types.Directories) error {
// Функция 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{}
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"
}
@@ -172,7 +156,7 @@ func buildContents(vars *types.BuildVars, dirs types.Directories, preferedConten
var RegexpALRPackageName = regexp.MustCompile(`^(?P<package>[^+]+)\+alr-(?P<repo>.+)$`)
func getBasePkgInfo(vars *types.BuildVars, input interface {
func getBasePkgInfo(vars *alrsh.Package, input interface {
RepositoryProvider
OsInfoProvider
},
@@ -228,39 +212,39 @@ func createBuildEnvVars(info *distro.OSRelease, dirs types.Directories) []string
}
// Функция setScripts добавляет скрипты-перехватчики к метаданным пакета.
func setScripts(vars *types.BuildVars, info *nfpm.Info, scriptDir string) {
if vars.Scripts.PreInstall != "" {
info.Scripts.PreInstall = filepath.Join(scriptDir, vars.Scripts.PreInstall)
func setScripts(vars *alrsh.Package, info *nfpm.Info, scriptDir string) {
if vars.Scripts.Resolved().PreInstall != "" {
info.Scripts.PreInstall = filepath.Join(scriptDir, vars.Scripts.Resolved().PreInstall)
}
if vars.Scripts.PostInstall != "" {
info.Scripts.PostInstall = filepath.Join(scriptDir, vars.Scripts.PostInstall)
if vars.Scripts.Resolved().PostInstall != "" {
info.Scripts.PostInstall = filepath.Join(scriptDir, vars.Scripts.Resolved().PostInstall)
}
if vars.Scripts.PreRemove != "" {
info.Scripts.PreRemove = filepath.Join(scriptDir, vars.Scripts.PreRemove)
if vars.Scripts.Resolved().PreRemove != "" {
info.Scripts.PreRemove = filepath.Join(scriptDir, vars.Scripts.Resolved().PreRemove)
}
if vars.Scripts.PostRemove != "" {
info.Scripts.PostRemove = filepath.Join(scriptDir, vars.Scripts.PostRemove)
if vars.Scripts.Resolved().PostRemove != "" {
info.Scripts.PostRemove = filepath.Join(scriptDir, vars.Scripts.Resolved().PostRemove)
}
if vars.Scripts.PreUpgrade != "" {
info.ArchLinux.Scripts.PreUpgrade = filepath.Join(scriptDir, vars.Scripts.PreUpgrade)
info.APK.Scripts.PreUpgrade = filepath.Join(scriptDir, vars.Scripts.PreUpgrade)
if vars.Scripts.Resolved().PreUpgrade != "" {
info.ArchLinux.Scripts.PreUpgrade = filepath.Join(scriptDir, vars.Scripts.Resolved().PreUpgrade)
info.APK.Scripts.PreUpgrade = filepath.Join(scriptDir, vars.Scripts.Resolved().PreUpgrade)
}
if vars.Scripts.PostUpgrade != "" {
info.ArchLinux.Scripts.PostUpgrade = filepath.Join(scriptDir, vars.Scripts.PostUpgrade)
info.APK.Scripts.PostUpgrade = filepath.Join(scriptDir, vars.Scripts.PostUpgrade)
if vars.Scripts.Resolved().PostUpgrade != "" {
info.ArchLinux.Scripts.PostUpgrade = filepath.Join(scriptDir, vars.Scripts.Resolved().PostUpgrade)
info.APK.Scripts.PostUpgrade = filepath.Join(scriptDir, vars.Scripts.Resolved().PostUpgrade)
}
if vars.Scripts.PreTrans != "" {
info.RPM.Scripts.PreTrans = filepath.Join(scriptDir, vars.Scripts.PreTrans)
if vars.Scripts.Resolved().PreTrans != "" {
info.RPM.Scripts.PreTrans = filepath.Join(scriptDir, vars.Scripts.Resolved().PreTrans)
}
if vars.Scripts.PostTrans != "" {
info.RPM.Scripts.PostTrans = filepath.Join(scriptDir, vars.Scripts.PostTrans)
if vars.Scripts.Resolved().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/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/repos"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
)
type AppDeps struct {
@@ -123,8 +123,15 @@ func (b *AppBuilder) withRepos(enablePull, forcePull bool) *AppBuilder {
cfg := b.deps.Cfg
db := b.deps.DB
if cfg == nil || db == nil {
b.err = errors.New("config and db are required before initializing repos")
info := b.deps.Info
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
}

View File

@@ -28,8 +28,8 @@ import (
"github.com/AlecAivazis/survey/v2"
"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/pkg/alrsh"
)
// 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
// 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 {
var outPkgs []db.Package
func FlattenPkgs(ctx context.Context, found map[string][]alrsh.Package, verb string, interactive bool) []alrsh.Package {
var outPkgs []alrsh.Package
for _, pkgs := range found {
if len(pkgs) > 1 && 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.
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 {
return options[0], nil
}
@@ -138,7 +138,7 @@ func PkgPrompt(ctx context.Context, options []db.Package, verb string, interacti
var choice int
err := survey.AskOne(prompt, &choice)
if err != nil {
return db.Package{}, err
return alrsh.Package{}, err
}
return options[choice], nil

View File

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

View File

@@ -29,7 +29,7 @@ import (
"github.com/pelletier/go-toml/v2"
"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 {

View File

@@ -23,41 +23,18 @@ import (
"context"
"log/slog"
"github.com/jmoiron/sqlx"
"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/pkg/alrsh"
)
// CurrentVersion is the current version of the database.
// The database is reset if its version doesn't match this.
const CurrentVersion = 4
const CurrentVersion = 5
// Package is a ALR package's database representation
type Package struct {
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 Version struct {
Version int `xorm:"'version'"`
}
type Config interface {
@@ -65,7 +42,7 @@ type Config interface {
}
type Database struct {
conn *sqlx.DB
engine *xorm.Engine
config Config
}
@@ -75,181 +52,100 @@ func New(config Config) *Database {
}
}
func (d *Database) Init(ctx context.Context) error {
err := d.Connect(ctx)
if err != nil {
return err
}
return d.initDB(ctx)
}
func (d *Database) Connect(ctx context.Context) error {
func (d *Database) Connect() error {
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 {
return err
}
d.conn = db
d.engine = engine
return nil
}
func (d *Database) GetConn() *sqlx.DB {
return d.conn
}
func (d *Database) initDB(ctx context.Context) error {
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 {
func (d *Database) Init(ctx context.Context) error {
if err := d.Connect(); err != nil {
return err
}
if err := d.engine.Sync2(new(alrsh.Package), new(Version)); err != nil {
return err
}
ver, ok := d.GetVersion(ctx)
if ok && ver != CurrentVersion {
slog.Warn(gotext.Get("Database version mismatch; resetting"), "version", ver, "expected", CurrentVersion)
err = d.reset(ctx)
if err != nil {
if err := d.reset(); err != nil {
return err
}
return d.initDB(ctx)
return d.Init(ctx)
} else if !ok {
slog.Warn(gotext.Get("Database version does not exist. Run alr fix if something isn't working."), "version", ver, "expected", CurrentVersion)
return d.addVersion(ctx, CurrentVersion)
slog.Warn(gotext.Get("Database version does not exist. Run alr fix if something isn't working."))
return d.addVersion(CurrentVersion)
}
return nil
}
func (d *Database) GetVersion(ctx context.Context) (int, bool) {
var ver version
err := d.conn.GetContext(ctx, &ver, "SELECT * FROM alr_db_version LIMIT 1;")
if err != nil {
var v Version
has, err := d.engine.Get(&v)
if err != nil || !has {
return 0, false
}
return ver.Version, true
return v.Version, true
}
func (d *Database) addVersion(ctx context.Context, ver int) error {
_, err := d.conn.ExecContext(ctx, `INSERT INTO alr_db_version(version) VALUES (?);`, ver)
func (d *Database) addVersion(ver int) error {
_, err := d.engine.Insert(&Version{Version: ver})
return err
}
func (d *Database) reset(ctx context.Context) error {
_, err := d.conn.ExecContext(ctx, "DROP TABLE IF EXISTS pkgs;")
func (d *Database) reset() error {
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 {
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
}
}
func (d *Database) GetPkgs(ctx context.Context, where string, args ...any) (*sqlx.Rows, error) {
stream, err := d.conn.QueryxContext(ctx, "SELECT * FROM pkgs WHERE "+where, args...)
if err != nil {
return nil
}
func (d *Database) GetPkgs(_ context.Context, where string, args ...any) ([]alrsh.Package, error) {
var pkgs []alrsh.Package
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 stream, nil
return &pkg, nil
}
func (d *Database) GetPkg(ctx context.Context, where string, args ...any) (*Package, error) {
out := &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...)
func (d *Database) DeletePkgs(_ context.Context, where string, args ...any) error {
_, err := d.engine.Where(where, args...).Delete(&alrsh.Package{})
return err
}
func (d *Database) IsEmpty(ctx context.Context) bool {
var count int
err := d.conn.GetContext(ctx, &count, "SELECT count(1) FROM pkgs;")
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) IsEmpty() bool {
count, err := d.engine.Count(new(alrsh.Package))
return err != nil || count == 0
}
func (d *Database) Close() error {
if d.conn != nil {
return d.conn.Close()
} else {
return nil
}
return d.engine.Close()
}

View File

@@ -25,10 +25,11 @@ import (
"strings"
"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/db"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
)
type TestALRConfig struct{}
@@ -45,35 +46,38 @@ func prepareDb() *db.Database {
return database
}
var testPkg = db.Package{
var testPkg = alrsh.Package{
Name: "test",
Version: "0.0.1",
Release: 1,
Epoch: 2,
Description: db.NewJSON(map[string]string{
Description: alrsh.OverridableFromMap(map[string]string{
"en": "Test package",
"ru": "Проверочный пакет",
}),
Homepage: db.NewJSON(map[string]string{
Homepage: alrsh.OverridableFromMap(map[string]string{
"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>",
"ru": "Евгений Храмов <xpamych@yandex.ru>",
}),
Architectures: db.NewJSON([]string{"arm64", "amd64"}),
Licenses: db.NewJSON([]string{"GPL-3.0-or-later"}),
Provides: db.NewJSON([]string{"test"}),
Conflicts: db.NewJSON([]string{"test"}),
Replaces: db.NewJSON([]string{"test-old"}),
Depends: db.NewJSON(map[string][]string{
Architectures: []string{"arm64", "amd64"},
Licenses: []string{"GPL-3.0-or-later"},
Provides: []string{"test"},
Conflicts: []string{"test"},
Replaces: []string{"test-old"},
Depends: alrsh.OverridableFromMap(map[string][]string{
"": {"sudo"},
}),
BuildDepends: db.NewJSON(map[string][]string{
BuildDepends: alrsh.OverridableFromMap(map[string][]string{
"": {"golang"},
"arch": {"go"},
}),
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) {
@@ -99,15 +103,16 @@ func TestInsertPackage(t *testing.T) {
t.Fatalf("Expected no error, got %s", err)
}
dbPkg := db.Package{}
err = sqlx.Get(database.GetConn(), &dbPkg, "SELECT * FROM pkgs WHERE name = 'test' AND repository = 'default'")
pkgs, err := database.GetPkgs(ctx, "name = 'test' AND repository = 'default'")
if err != nil {
t.Fatalf("Expected no error, got %s", err)
}
if !reflect.DeepEqual(testPkg, dbPkg) {
t.Errorf("Expected test package to be the same as database package")
if len(pkgs) != 1 {
t.Fatalf("Expected 1 package, got %d", len(pkgs))
}
assert.Equal(t, testPkg, pkgs[0])
}
func TestGetPkgs(t *testing.T) {
@@ -130,18 +135,12 @@ func TestGetPkgs(t *testing.T) {
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 {
t.Fatalf("Expected no error, got %s", err)
}
for result.Next() {
var dbPkg db.Package
err = result.StructScan(&dbPkg)
if err != nil {
t.Errorf("Expected no error, got %s", err)
}
for _, dbPkg := range pkgs {
if !strings.HasPrefix(dbPkg.Name, "x") {
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)
}
pkg, err := database.GetPkg(ctx, "name LIKE 'x%' ORDER BY name")
pkg, err := database.GetPkg("name LIKE 'x%'")
if err != nil {
t.Fatalf("Expected no error, got %s", err)
}
@@ -206,16 +205,6 @@ func TestDeletePkgs(t *testing.T) {
if err != nil {
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) {
@@ -227,7 +216,7 @@ func TestJsonArrayContains(t *testing.T) {
x1.Name = "x1"
x2 := testPkg
x2.Name = "x2"
x2.Provides.Val = append(x2.Provides.Val, "x")
x2.Provides = append(x2.Provides, "x")
err := database.InsertPackage(ctx, x1)
if err != nil {
@@ -239,13 +228,24 @@ func TestJsonArrayContains(t *testing.T) {
t.Errorf("Expected no error, got %s", err)
}
var dbPkg db.Package
err = database.GetConn().Get(&dbPkg, "SELECT * FROM pkgs WHERE json_array_contains(provides, 'x');")
pkgs, err := database.GetPkgs(ctx, "name = 'x2'")
if err != nil {
t.Fatalf("Expected no error, got %s", err)
}
if dbPkg.Name != "x2" {
t.Errorf("Expected x2 package, got %s", dbPkg.Name)
if len(pkgs) != 1 || pkgs[0].Name != "x2" {
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 (
"fmt"
"reflect"
"regexp"
"strings"
@@ -29,8 +28,7 @@ import (
"golang.org/x/text/language"
"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/internal/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
)
type Opts struct {
@@ -150,65 +148,6 @@ func (o *Opts) WithLanguageTags(langs []string) *Opts {
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) {
out := make([]string, len(tags)+len(langs))
for i, tag := range tags {

View File

@@ -27,8 +27,8 @@ import (
"github.com/stretchr/testify/assert"
"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/pkg/distro"
)
var info = &distro.OSRelease{

View File

@@ -22,11 +22,11 @@ package repos
import (
"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) {
found := map[string][]db.Package{}
func (rs *Repos) FindPkgs(ctx context.Context, pkgs []string) (map[string][]alrsh.Package, []string, error) {
found := map[string][]alrsh.Package{}
notFound := []string(nil)
for _, pkgName := range pkgs {
@@ -40,17 +40,10 @@ func (rs *Repos) FindPkgs(ctx context.Context, pkgs []string) (map[string][]db.P
}
added := 0
for result.Next() {
var pkg db.Package
err = result.StructScan(&pkg)
if err != nil {
return nil, nil, err
}
for _, pkg := range result {
added++
found[pkgName] = append(found[pkgName], pkg)
}
result.Close()
if added == 0 {
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
}
for result.Next() {
var pkg db.Package
err = result.StructScan(&pkg)
if err != nil {
return nil, nil, err
}
for _, pkg := range result {
added++
found[pkgName] = append(found[pkgName], pkg)
}
result.Close()
}
if added == 0 {

View File

@@ -24,9 +24,9 @@ import (
"strings"
"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/types"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
)
func TestFindPkgs(t *testing.T) {
@@ -89,31 +89,31 @@ func TestFindPkgsEmpty(t *testing.T) {
e.Db,
)
err := e.Db.InsertPackage(e.Ctx, db.Package{
err := e.Db.InsertPackage(e.Ctx, alrsh.Package{
Name: "test1",
Repository: "default",
Version: "0.0.1",
Release: 1,
Description: db.NewJSON(map[string]string{
Provides: []string{""},
Description: alrsh.OverridableFromMap(map[string]string{
"en": "Test package 1",
"ru": "Проверочный пакет 1",
}),
Provides: db.NewJSON([]string{""}),
})
if err != nil {
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",
Repository: "default",
Version: "0.0.1",
Release: 1,
Description: db.NewJSON(map[string]string{
Provides: []string{"test"},
Description: alrsh.OverridableFromMap(map[string]string{
"en": "Test package 2",
"ru": "Проверочный пакет 2",
}),
Provides: db.NewJSON([]string{"test"}),
})
if err != nil {
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/shutils/handlers"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
)
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
// empty. In this case, we need to update the DB fully
// rather than just incrementally.
if rs.db.IsEmpty(ctx) {
if rs.db.IsEmpty() {
err = rs.processRepoFull(ctx, repo, repoDir)
if err != nil {
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/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{}
@@ -84,16 +85,10 @@ build_deps=('golang')
result, err := database.GetPkgs(ctx, "1 = 1")
assert.NoError(t, err)
pkgCount := 0
for result.Next() {
var dbPkg db.Package
err = result.StructScan(&dbPkg)
if err != nil {
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)
for _, pkg := range result {
assert.Equal(t, "foo", pkg.Name)
assert.Equal(t, alrsh.OverridableFromMap(map[string]string{"": "main desc"}), pkg.Description)
assert.Equal(t, alrsh.OverridableFromMap(map[string][]string{"": {"sudo"}}), pkg.Depends)
pkgCount++
}
assert.Equal(t, 1, pkgCount)
@@ -125,20 +120,18 @@ meta_buz() {
assert.NoError(t, err)
pkgCount := 0
for result.Next() {
var dbPkg db.Package
err = result.StructScan(&dbPkg)
for _, pkg := range result {
if err != nil {
t.Errorf("Expected no error, got %s", err)
}
if dbPkg.Name == "bar" {
assert.Equal(t, db.NewJSON(map[string]string{"": "foo desc"}), dbPkg.Description)
assert.Equal(t, db.NewJSON(map[string][]string{"": {"sudo"}}), dbPkg.Depends)
if pkg.Name == "bar" {
assert.Equal(t, alrsh.OverridableFromMap(map[string]string{"": "foo desc"}), pkg.Description)
assert.Equal(t, alrsh.OverridableFromMap(map[string][]string{"": {"sudo"}}), pkg.Depends)
}
if dbPkg.Name == "buz" {
assert.Equal(t, db.NewJSON(map[string]string{"": "main desc"}), dbPkg.Description)
assert.Equal(t, db.NewJSON(map[string][]string{"": {"sudo", "doas"}}), dbPkg.Depends)
if pkg.Name == "buz" {
assert.Equal(t, alrsh.OverridableFromMap(map[string]string{"": "main desc"}), pkg.Description)
assert.Equal(t, alrsh.OverridableFromMap(map[string][]string{"": {"sudo", "doas"}}), pkg.Depends)
}
pkgCount++
}

View File

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

View File

@@ -19,7 +19,7 @@ package repos
import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
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 {

View File

@@ -18,12 +18,9 @@ package repos
import (
"context"
"errors"
"fmt"
"io"
"path/filepath"
"reflect"
"strings"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
@@ -34,11 +31,9 @@ import (
"mvdan.cc/sh/v3/interp"
"mvdan.cc/sh/v3/syntax"
"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/parser"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/decoder"
"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"
)
// isValid makes sure the path of the file being updated is valid.
@@ -63,152 +58,21 @@ func parseScript(
syntaxParser *syntax.Parser,
runner *interp.Runner,
r io.ReadCloser,
) ([]*db.Package, error) {
fl, err := syntaxParser.Parse(r, "alr.sh")
) ([]*alrsh.Package, error) {
f, err := alrsh.ReadFromIOReader(r, "/tmp")
if err != nil {
return nil, err
}
runner.Reset()
err = runner.Run(ctx, fl)
_, dbPkgs, err := f.ParseBuildVars(ctx, &distro.OSRelease{}, []string{})
if err != nil {
return nil, err
}
d := decoder.New(&distro.OSRelease{}, runner)
d.Overrides = false
d.LikeDistros = false
pkgNames, err := parser.ParseNames(d)
if err != nil {
return nil, fmt.Errorf("failed parsing package names: %w", err)
for _, pkg := range dbPkgs {
pkg.Repository = repo.Name
}
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
}
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) {
remote, err := r.Remote(git.DefaultRemoteName)
if err != nil {

View File

@@ -22,13 +22,11 @@ package search
import (
"context"
"github.com/jmoiron/sqlx"
database "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
)
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 {
@@ -44,23 +42,8 @@ func New(pp PackagesProvider) *Searcher {
func (s *Searcher) Search(
ctx context.Context,
opts *SearchOptions,
) ([]database.Package, error) {
var packages []database.Package
) ([]alrsh.Package, error) {
where, args := opts.WhereClause()
result, err := s.pp.GetPkgs(ctx, where, args...)
if err != nil {
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
packages, err := s.pp.GetPkgs(ctx, where, args...)
return packages, err
}

View File

@@ -22,6 +22,8 @@ package decoder
import (
"context"
"errors"
"fmt"
"log/slog"
"reflect"
"strings"
@@ -31,8 +33,8 @@ import (
"mvdan.cc/sh/v3/interp"
"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/pkg/distro"
)
var ErrNotPointerToStruct = errors.New("val must be a pointer to a struct")
@@ -52,7 +54,7 @@ type InvalidTypeError struct {
}
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
@@ -81,13 +83,48 @@ func (d *Decoder) DecodeVar(name string, val any) error {
dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
WeaklyTypedInput: true,
DecodeHook: mapstructure.DecodeHookFuncValue(func(from, to reflect.Value) (interface{}, error) {
if strings.Contains(to.Type().String(), "db.JSON") {
valType := to.FieldByName("Val").Type()
if !from.Type().AssignableTo(valType) {
return nil, InvalidTypeError{name, from.Type().String(), valType.String()}
if strings.Contains(to.Type().String(), "alrsh.OverridableField") {
if to.Kind() != reflect.Ptr && to.CanAddr() {
to = to.Addr()
}
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 from.Interface(), nil
@@ -96,6 +133,7 @@ func (d *Decoder) DecodeVar(name string, val any) error {
TagName: "sh",
})
if err != nil {
slog.Warn("err", "err", err)
return err
}
@@ -255,7 +293,16 @@ func (d *Decoder) getVar(name string) *expand.Variable {
}
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 {
// Resolve nameref variables
_, resolved := val.Resolve(expand.FuncEnviron(func(s string) string {
@@ -268,7 +315,6 @@ func (d *Decoder) getVar(name string) *expand.Variable {
return &val
}
}
return nil
}

View File

@@ -31,8 +31,8 @@ import (
"mvdan.cc/sh/v3/interp"
"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/pkg/distro"
)
type BuildVars struct {

View File

@@ -27,9 +27,9 @@ import (
"mvdan.cc/sh/v3/interp"
"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/handlers"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
)
const testScript = `

View File

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

View File

@@ -133,71 +133,67 @@ msgstr "Показывать всю информацию, не только дл
msgid "Error getting packages"
msgstr "Ошибка при получении пакетов"
#: info.go:76
msgid "Error iterating over packages"
msgstr "Ошибка при переборе пакетов"
#: info.go:90
#: info.go:83
msgid "Command info expected at least 1 argument, got %d"
msgstr "Для команды info ожидался хотя бы 1 аргумент, получено %d"
#: info.go:110
#: info.go:104
msgid "Error finding packages"
msgstr "Ошибка при поиске пакетов"
#: info.go:124
#: info.go:118
msgid "Can't detect system language"
msgstr "Ошибка при определении языка системы"
#: info.go:141
#: info.go:135
msgid "Error resolving overrides"
msgstr "Ошибка устранения переорпеделений"
#: info.go:149 info.go:154
#: info.go:144 info.go:149
msgid "Error encoding script variables"
msgstr "Ошибка кодирования переменных скрита"
#: install.go:40
#: install.go:39
msgid "Install a new package"
msgstr "Установить новый пакет"
#: install.go:52
#: install.go:51
msgid "Command install expected at least 1 argument, got %d"
msgstr "Для команды install ожидался хотя бы 1 аргумент, получено %d"
#: install.go:114
#: install.go:113
msgid "Error when installing the package"
msgstr "Ошибка при установке пакета"
#: install.go:159
#: install.go:151
msgid "Remove an installed package"
msgstr "Удалить установленный пакет"
#: install.go:178
#: install.go:170
msgid "Error listing installed packages"
msgstr "Ошибка при составлении списка установленных пакетов"
#: install.go:215
#: install.go:199
msgid "Command remove expected at least 1 argument, got %d"
msgstr "Для команды remove ожидался хотя бы 1 аргумент, получено %d"
#: install.go:230
#: install.go:214
msgid "Error removing packages"
msgstr "Ошибка при удалении пакетов"
#: internal/build/build.go:417
#: internal/build/build.go:376
msgid "Building package"
msgstr "Сборка пакета"
#: internal/build/build.go:446
#: internal/build/build.go:405
msgid "The checksums array must be the same length as sources"
msgstr "Массив контрольных сумм должен быть той же длины, что и источники"
#: internal/build/build.go:488
#: internal/build/build.go:447
msgid "Downloading sources"
msgstr "Скачивание источников"
#: internal/build/build.go:580
#: internal/build/build.go:539
msgid "Installing dependencies"
msgstr "Установка зависимостей"
@@ -235,19 +231,19 @@ msgid "AutoReq is not implemented for this package format, so it's skipped"
msgstr ""
"AutoReq не реализовано для этого формата пакета, поэтому будет пропущено"
#: internal/build/script_executor.go:236
#: internal/build/script_executor.go:145
msgid "Building package metadata"
msgstr "Сборка метаданных пакета"
#: internal/build/script_executor.go:366
#: internal/build/script_executor.go:276
msgid "Executing prepare()"
msgstr "Выполнение prepare()"
#: internal/build/script_executor.go:375
#: internal/build/script_executor.go:285
msgid "Executing 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()"
msgstr "Выполнение %s()"
@@ -259,15 +255,15 @@ msgstr "Ошибка при загрузке"
msgid "Error initialization database"
msgstr "Ошибка инициализации базы данных"
#: internal/cliutils/app_builder/builder.go:135
#: internal/cliutils/app_builder/builder.go:142
msgid "Error pulling repositories"
msgstr "Ошибка при извлечении репозиториев"
#: internal/cliutils/app_builder/builder.go:152
#: internal/cliutils/app_builder/builder.go:159
msgid "Error parsing os release"
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"
msgstr "Не удалось обнаружить поддерживаемый менеджер пакетов в системе"
@@ -351,7 +347,7 @@ msgstr "КАТЕГОРИЯ"
msgid "OPTIONS"
msgstr "ПАРАМЕТРЫ"
#: internal/cliutils/utils.go:69
#: internal/cliutils/utils.go:72
msgid ""
"This command is deprecated and would be removed in the future, use \"%s\" "
"instead!"
@@ -359,11 +355,11 @@ msgstr ""
"Эта команда устарела и будет удалена в будущем, используйте вместо нее \"%s"
"\"!"
#: internal/db/db.go:137
#: internal/db/db.go:76
msgid "Database version mismatch; resetting"
msgstr "Несоответствие версий базы данных; сброс настроек"
#: internal/db/db.go:144
#: internal/db/db.go:82
msgid ""
"Database version does not exist. Run alr fix if something isn't working."
msgstr ""
@@ -445,11 +441,11 @@ msgstr "Ошибка при получении пакетов для обнов
msgid "No packages for upgrade"
msgstr "Нет пакетов к обновлению"
#: list.go:102 list.go:187
#: list.go:102 list.go:184
msgid "Error parsing format template"
msgstr "Ошибка при разборе шаблона"
#: list.go:108 list.go:191
#: list.go:108 list.go:188
msgid "Error executing template"
msgstr "Ошибка при выполнении шаблона"
@@ -561,18 +557,21 @@ msgstr "Иcкать по provides"
msgid "Error while executing search"
msgstr "Ошибка при выполнении поиска"
#: upgrade.go:47
#: upgrade.go:48
msgid "Upgrade all installed packages"
msgstr "Обновить все установленные пакеты"
#: upgrade.go:105 upgrade.go:122
#: upgrade.go:106 upgrade.go:123
msgid "Error checking for updates"
msgstr "Ошибка при проверке обновлений"
#: upgrade.go:125
#: upgrade.go:126
msgid "There is nothing to do."
msgstr "Здесь нечего делать."
#~ msgid "Error iterating over packages"
#~ msgstr "Ошибка при переборе пакетов"
#~ msgid "Error pulling repos"
#~ 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/cliutils"
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/utils"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/alrsh"
)
func ListCmd() *cli.Command {
@@ -69,9 +69,9 @@ func ListCmd() *cli.Command {
WithConfig().
WithDB().
WithManager().
WithDistroInfo().
// autoPull only
WithRepos().
WithDistroInfo().
Build()
if err != nil {
return err
@@ -125,7 +125,6 @@ func ListCmd() *cli.Command {
if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error getting packages"), err)
}
defer result.Close()
installedAlrPackages := map[string]string{}
if c.Bool("installed") {
@@ -150,9 +149,7 @@ func ListCmd() *cli.Command {
}
}
for result.Next() {
var pkg database.Package
err := result.StructScan(&pkg)
for _, pkg := range result {
if err != nil {
return cli.Exit(err, 1)
}
@@ -162,7 +159,7 @@ func ListCmd() *cli.Command {
}
type packageInfo struct {
Package *database.Package
Package *alrsh.Package
Version string
}

View File

@@ -52,9 +52,9 @@
./internal/translations/files/lure.en.toml
./internal/translations/files/lure.ru.toml
./internal/translations/translations.go
./internal/types/build.go
./internal/types/config.go
./internal/types/repo.go
./pkg/types/build.go
./pkg/types/config.go
./pkg/types/repo.go
./list.go
./main.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
}
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 {
PreInstall string `sh:"preinstall"`
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"
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/pkg/types"
)
func RepoCmd() *cli.Command {

View File

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

View File

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