17 Commits

Author SHA1 Message Date
9cf8af08ab Merge pull request 'fix: remove duplicates correctly' (#46) from Maks1mS/ALR:fix/remove-duplicates-correctly into master
Reviewed-on: Plemya-x/ALR#46
2025-03-13 13:44:40 +00:00
86940e8962 tests: add TestRemoveDuplicatesSources 2025-03-13 16:38:36 +03:00
db244204c7 fix: remove duplicates correctly 2025-03-13 16:24:37 +03:00
9cb0a5e9ad Merge pull request 'chore: update package name in Makefile' (#45) from Maks1mS/ALR:fix/correct-set-version into master
Reviewed-on: Plemya-x/ALR#45
2025-03-12 15:18:01 +00:00
1a57ccdb83 chore: update package name in Makefile 2025-03-12 15:11:19 +03:00
615cd83fb7 Merge pull request 'fix: resolve absolute path of ScriptDir' (#44) from Maks1mS/ALR:fix/use-abs-scriptdir-path into master
Reviewed-on: Plemya-x/ALR#44
2025-03-11 17:30:49 +00:00
27e2f54653 fix: resolve absolute path of ScriptDir 2025-03-11 20:28:41 +03:00
af57165c89 Небольшие правки и исправления. 2025-03-10 14:50:02 +03:00
3770c82240 Merge pull request 'fix: add db.Init() in bash completion' (#42) from Maks1mS/ALR:fix/add-db-init-in-completion into master
Reviewed-on: Plemya-x/ALR#42
2025-03-09 20:59:05 +00:00
2dff463303 i18n: update ru translation 2025-03-09 17:32:19 +03:00
9085e38454 fix: add db.Init() in bash completion 2025-03-09 17:30:02 +03:00
a7d016abc9 Замена устаревшего метода установки в шаблоне alr gen pip 2025-03-02 13:50:11 +03:00
4a5cca2d0f Замена устаревшего метода установки в шаблоне alr gen pip 2025-03-02 13:34:22 +03:00
71000fd3cd Merge pull request 'fix: use unique names for packages' (#40) from Maks1mS/ALR:fix/use-unique-package-name into master
Reviewed-on: Plemya-x/ALR#40
2025-03-02 06:49:52 +00:00
71968bbe13 fix: fix config saving 2025-02-28 21:14:59 +03:00
29c1a31066 fix: fix list and upgrade commands with new naming 2025-02-28 21:14:21 +03:00
8f94b61a0e fix: use +alr-{reponame} suffix 2025-02-28 20:15:02 +03:00
17 changed files with 387 additions and 280 deletions

View File

@ -21,7 +21,7 @@ build: check-no-root $(BIN)
export CGO_ENABLED := 0 export CGO_ENABLED := 0
$(BIN): $(BIN):
go build -ldflags="-X 'gitea.plemya-x.ru/xpamych/ALR/internal/config.Version=$(GIT_VERSION)'" -o $@ go build -ldflags="-X 'gitea.plemya-x.ru/Plemya-x/ALR/internal/config.Version=$(GIT_VERSION)'" -o $@
check-no-root: check-no-root:
@if [[ "$$(whoami)" == 'root' ]]; then \ @if [[ "$$(whoami)" == 'root' ]]; then \

View File

@ -7,9 +7,9 @@
# ALR (Any Linux Repository) # ALR (Any Linux Repository)
ALR - это независимая от дистрибутива система сборки для Linux, аналогичная [AUR](https://wiki.archlinux.org/title/Arch_User_Repository). В настоящее время она находится в стадии бета-тестирования. Исправлено большинство основных ошибок и добавлено большинство важных функций. alr готов к общему использованию, но все еще может время от времени ломаться или заменяться. ALR - это независимая от дистрибутива система сборки для Linux (форк [LURE](https://github.com/lure-sh/lure), аналогичная [AUR](https://wiki.archlinux.org/title/Arch_User_Repository). В настоящее время она находится в стадии бета-тестирования. Исправлено большинство основных ошибок и добавлено большинство важных функций. ALR готов к общему использованию, но все еще может время от времени ломаться или изменяться.
ALR написан на чистом Go и после сборки не имеет зависимостей. Единственное, для повышения привилегий ALR требуется команда, такая как `sudo`, `doas` и т.д., а также поддерживаемый менеджер пакетов. В настоящее время ALR поддерживает `apt`, `pacman`, `apk`, `dnf`, `yum`, and `zypper`. Если в вашей системе существует поддерживаемый менеджер пакетов, он будет обнаружен и использован автоматически. ALR написан на чистом Go и после сборки не имеет зависимостей. Для повышения привилегий ALR требуется команда, такая как `sudo`, `doas` и т.д., а также поддерживаемый менеджер пакетов. В настоящее время ALR поддерживает `apt`, `apt-get` `pacman`, `apk`, `dnf`, `yum`, and `zypper`. Если в вашей системе используется поддерживаемый менеджер пакетов, то он будет обнаружен и использован автоматически.
--- ---
@ -23,14 +23,14 @@ ALR написан на чистом Go и после сборки не имее
curl -fsSL plemya-x.ru/alr/install.sh | bash curl -fsSL plemya-x.ru/alr/install.sh | bash
``` ```
**ВАЖНО**: При этом скрипт будет загружен и запущен с <https://gitea.plemya-x.ru/Plemya-x/ALR/src/branch/master/scripts/install.sh>. Пожалуйста, просматривайте любые скрипты, которые вы скачиваете из Интернета (включая этот), прежде чем запускать их. **ВАЖНО**: При этом скрипт будет загружен и запущен с <https://plemya-x.ru/alr/install.sh>. Пожалуйста, просматривайте любые скрипты, которые вы скачиваете из Интернета (включая этот), прежде чем запускать их.
### Сборка из исходного кода ### Сборка из исходного кода
Чтобы собрать ALR из исходного кода, вам понадобится версия Go 1.18 или новее. Как только Go будет установлен, клонируйте это репозиторий и запустите: Чтобы собрать ALR из исходного кода, вам понадобится версия Go 1.18 или новее. Как только Go будет установлен, клонируйте это репозиторий и запустите:
```shell ```shell
make build make build -B
sudo make install sudo make install
``` ```
@ -44,7 +44,7 @@ ALR был создан потому, что упаковка программн
## Документация ## Документация
Документация по всем этим вопросам находится в [Wiki](https://gitea.plemya-x.ru/xpamych/ALR/wiki/Home). Документация находится в [Wiki](https://disc.plemya-x.ru/c/alr/wiki-alr).
--- ---
@ -52,17 +52,15 @@ ALR был создан потому, что упаковка программн
Репозитории alr - это git-хранилища, которые содержат каталог для каждого пакета с файлом `alr.sh` внутри. Файл `alr.sh` содержит все инструкции по сборке пакета и информацию о нем. Скрипты `alr.sh` аналогичны скриптам Aur PKGBUILD. Репозитории alr - это git-хранилища, которые содержат каталог для каждого пакета с файлом `alr.sh` внутри. Файл `alr.sh` содержит все инструкции по сборке пакета и информацию о нем. Скрипты `alr.sh` аналогичны скриптам Aur PKGBUILD.
Например, репозиторий [Plemya-x/xpamych-alr-repo](https://gitea.plemya-x.ru/Plemya-x/xpamych-alr-repo.git) можно подключить так: Например, репозиторий [Plemya-x/alr-repo](https://gitea.plemya-x.ru/Plemya-x/alr-repo.git) можно подключить так:
``` ```
alr addrepo --name xpamych-alr-repo --url https://gitea.plemya-x.ru/Plemya-x/xpamych-alr-repo.git alr addrepo --name alr-repo --url https://gitea.plemya-x.ru/Plemya-x/alr-repo.git
``` ```
--- ---
## Соцсети ## Соцсети
VK - https://vk.com/plemya_kh VK - https://vk.com/plemya_kh
Discord - https://discord.com/channels/817759634105827358/1261631565084233749
Telegram - https://t.me/plemyakh Telegram - https://t.me/plemyakh
## Спасибы ## Спасибы
@ -75,3 +73,6 @@ Telegram - https://t.me/plemyakh
- <https://github.com/goreleaser/nfpm> - <https://github.com/goreleaser/nfpm>
- <https://github.com/charmbracelet/bubbletea> - <https://github.com/charmbracelet/bubbletea>
- <https://gitlab.com/cznic/sqlite> - <https://gitlab.com/cznic/sqlite>
Благодарим за активное участие в развитии проекта:
- Maks1mS <maxim@slipenko.com>

View File

@ -11,7 +11,7 @@
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"> <g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="33.5" y="15" fill="#010101" fill-opacity=".3">coverage</text> <text x="33.5" y="15" fill="#010101" fill-opacity=".3">coverage</text>
<text x="33.5" y="14">coverage</text> <text x="33.5" y="14">coverage</text>
<text x="86" y="15" fill="#010101" fill-opacity=".3">19.6%</text> <text x="86" y="15" fill="#010101" fill-opacity=".3">19.8%</text>
<text x="86" y="14">19.6%</text> <text x="86" y="14">19.8%</text>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 926 B

After

Width:  |  Height:  |  Size: 926 B

View File

@ -50,9 +50,9 @@ func BuildCmd() *cli.Command {
Usage: gotext.Get("Path to the build script"), Usage: gotext.Get("Path to the build script"),
}, },
&cli.StringFlag{ &cli.StringFlag{
Name: "script-package", Name: "subpackage",
Aliases: []string{"sp"}, Aliases: []string{"sb"},
Usage: gotext.Get("Specify package in script (for multi package script only)"), Usage: gotext.Get("Specify subpackage in script (for multi package script only)"),
}, },
&cli.StringFlag{ &cli.StringFlag{
Name: "package", Name: "package",
@ -78,8 +78,7 @@ func BuildCmd() *cli.Command {
var script string var script string
var packages []string var packages []string
repository := "default"
// Проверяем, установлен ли флаг script (-s)
repoDir := cfg.GetPaths(ctx).RepoDir repoDir := cfg.GetPaths(ctx).RepoDir
@ -106,11 +105,13 @@ func BuildCmd() *cli.Command {
os.Exit(1) os.Exit(1)
} }
repository = pkg[0].Repository
if pkg[0].BasePkgName != "" { if pkg[0].BasePkgName != "" {
script = filepath.Join(repoDir, pkg[0].Repository, pkg[0].BasePkgName, "alr.sh") script = filepath.Join(repoDir, repository, pkg[0].BasePkgName, "alr.sh")
packages = append(packages, pkg[0].Name) packages = append(packages, pkg[0].Name)
} else { } else {
script = filepath.Join(repoDir, pkg[0].Repository, pkg[0].Name, "alr.sh") script = filepath.Join(repoDir, repository, pkg[0].Name, "alr.sh")
} }
default: default:
script = filepath.Join(repoDir, "alr.sh") script = filepath.Join(repoDir, "alr.sh")
@ -142,6 +143,7 @@ func BuildCmd() *cli.Command {
ctx, ctx,
types.BuildOpts{ types.BuildOpts{
Packages: packages, Packages: packages,
Repository: repository,
Script: script, Script: script,
Manager: mgr, Manager: mgr,
Clean: c.Bool("clean"), Clean: c.Bool("clean"),

View File

@ -119,6 +119,11 @@ func InstallCmd() *cli.Command {
BashComplete: func(c *cli.Context) { BashComplete: func(c *cli.Context) {
cfg := config.New() cfg := config.New()
db := database.New(cfg) db := database.New(cfg)
err := db.Init(c.Context)
if err != nil {
slog.Error(gotext.Get("Error initialization database"), "err", err)
os.Exit(1)
}
result, err := db.GetPkgs(c.Context, "true") result, err := db.GetPkgs(c.Context, "true")
if err != nil { if err != nil {
slog.Error(gotext.Get("Error getting packages"), "err", err) slog.Error(gotext.Get("Error getting packages"), "err", err)

View File

@ -193,3 +193,7 @@ func (c *ALRConfig) RootCmd(ctx context.Context) string {
}) })
return c.cfg.RootCmd return c.cfg.RootCmd
} }
func (c *ALRConfig) Save(f *os.File) error {
return toml.NewEncoder(f).Encode(c.cfg)
}

View File

@ -91,7 +91,7 @@ func TestDownloadWithoutCache(t *testing.T) {
}, },
{ {
name: "git download", name: "git download",
path: "git+%s/git-downloader/git/Plemya-x/xpamych-alr-repo", path: "git+%s/git-downloader/git/Plemya-x/alr-repo",
expected: func(t *testing.T, err error, tmpdir string) { expected: func(t *testing.T, err error, tmpdir string) {
assert.NoError(t, err) assert.NoError(t, err)

View File

@ -18,7 +18,7 @@ msgid "Path to the build script"
msgstr "" msgstr ""
#: build.go:55 #: build.go:55
msgid "Specify package in script (for multi package script only)" msgid "Specify subpackage in script (for multi package script only)"
msgstr "" msgstr ""
#: build.go:60 #: build.go:60
@ -34,31 +34,31 @@ msgstr ""
msgid "Error initialization database" msgid "Error initialization database"
msgstr "" msgstr ""
#: build.go:105 #: build.go:104
msgid "Package not found" msgid "Package not found"
msgstr "" msgstr ""
#: build.go:123 #: build.go:124
msgid "Error pulling repositories" msgid "Error pulling repositories"
msgstr "" msgstr ""
#: build.go:131 #: build.go:132
msgid "Unable to detect a supported package manager on the system" msgid "Unable to detect a supported package manager on the system"
msgstr "" msgstr ""
#: build.go:137 #: build.go:138
msgid "Error parsing os release" msgid "Error parsing os release"
msgstr "" msgstr ""
#: build.go:158 #: build.go:160
msgid "Error building package" msgid "Error building package"
msgstr "" msgstr ""
#: build.go:165 #: build.go:167
msgid "Error getting working directory" msgid "Error getting working directory"
msgstr "" msgstr ""
#: build.go:174 #: build.go:176
msgid "Error moving the package" msgid "Error moving the package"
msgstr "" msgstr ""
@ -158,15 +158,15 @@ msgstr ""
msgid "Command install expected at least 1 argument, got %d" msgid "Command install expected at least 1 argument, got %d"
msgstr "" msgstr ""
#: install.go:146 #: install.go:151
msgid "Remove an installed package" msgid "Remove an installed package"
msgstr "" msgstr ""
#: install.go:151 #: install.go:156
msgid "Command remove expected at least 1 argument, got %d" msgid "Command remove expected at least 1 argument, got %d"
msgstr "" msgstr ""
#: install.go:163 #: install.go:168
msgid "Error removing packages" msgid "Error removing packages"
msgstr "" msgstr ""
@ -323,11 +323,11 @@ msgstr ""
msgid "ERROR" msgid "ERROR"
msgstr "" msgstr ""
#: list.go:40 #: list.go:41
msgid "List ALR repo packages" msgid "List ALR repo packages"
msgstr "" msgstr ""
#: list.go:91 #: list.go:92
msgid "Error listing installed packages" msgid "Error listing installed packages"
msgstr "" msgstr ""
@ -357,72 +357,80 @@ msgstr ""
msgid "Error while running app" msgid "Error while running app"
msgstr "" msgstr ""
#: pkg/build/build.go:153 #: pkg/build/build.go:156
msgid "Failed to prompt user to view build script" msgid "Failed to prompt user to view build script"
msgstr "" msgstr ""
#: pkg/build/build.go:157 #: pkg/build/build.go:160
msgid "Building package" msgid "Building package"
msgstr "" msgstr ""
#: pkg/build/build.go:228 #: pkg/build/build.go:208
msgid "The checksums array must be the same length as sources"
msgstr ""
#: pkg/build/build.go:235
msgid "Downloading sources" msgid "Downloading sources"
msgstr "" msgstr ""
#: pkg/build/build.go:246 #: pkg/build/build.go:257
msgid "Building package metadata" msgid "Building package metadata"
msgstr "" msgstr ""
#: pkg/build/build.go:268 #: pkg/build/build.go:279
msgid "Compressing package" msgid "Compressing package"
msgstr "" msgstr ""
#: pkg/build/build.go:421 #: pkg/build/build.go:438
msgid "" msgid ""
"Your system's CPU architecture doesn't match this package. Do you want to " "Your system's CPU architecture doesn't match this package. Do you want to "
"build anyway?" "build anyway?"
msgstr "" msgstr ""
#: pkg/build/build.go:435 #: pkg/build/build.go:452
msgid "This package is already installed" msgid "This package is already installed"
msgstr "" msgstr ""
#: pkg/build/build.go:459 #: pkg/build/build.go:476
msgid "Installing build dependencies" msgid "Installing build dependencies"
msgstr "" msgstr ""
#: pkg/build/build.go:500 #: pkg/build/build.go:517
msgid "Installing dependencies" msgid "Installing dependencies"
msgstr "" msgstr ""
#: pkg/build/build.go:535 #: pkg/build/build.go:598
msgid "The checksums array must be the same length as sources"
msgstr ""
#: pkg/build/build.go:586
msgid "Would you like to remove the build dependencies?" msgid "Would you like to remove the build dependencies?"
msgstr "" msgstr ""
#: pkg/build/build.go:649 #: pkg/build/build.go:661
msgid "Executing prepare()" msgid "Executing prepare()"
msgstr "" msgstr ""
#: pkg/build/build.go:659 #: pkg/build/build.go:671
msgid "Executing build()" msgid "Executing build()"
msgstr "" msgstr ""
#: pkg/build/build.go:689 pkg/build/build.go:709 #: pkg/build/build.go:701 pkg/build/build.go:721
msgid "Executing %s()" msgid "Executing %s()"
msgstr "" msgstr ""
#: pkg/build/build.go:768 #: pkg/build/build.go:780
msgid "Error installing native packages" msgid "Error installing native packages"
msgstr "" msgstr ""
#: pkg/build/build.go:792 #: pkg/build/build.go:804
msgid "Error installing package" msgid "Error installing package"
msgstr "" msgstr ""
#: pkg/build/build.go:863
msgid "AutoProv is not implemented for this package format, so it's skipped"
msgstr ""
#: pkg/build/build.go:874
msgid "AutoReq is not implemented for this package format, so it's skipped"
msgstr ""
#: pkg/build/findDeps.go:35 #: pkg/build/findDeps.go:35
msgid "Command not found on the system" msgid "Command not found on the system"
msgstr "" msgstr ""
@ -435,14 +443,6 @@ msgstr ""
msgid "Required dependency found" msgid "Required dependency found"
msgstr "" msgstr ""
#: pkg/build/utils.go:133
msgid "AutoProv is not implemented for this package format, so it's skipped"
msgstr ""
#: pkg/build/utils.go:144
msgid "AutoReq is not implemented for this package format, so it's skipped"
msgstr ""
#: pkg/repos/pull.go:79 #: pkg/repos/pull.go:79
msgid "Pulling repository" msgid "Pulling repository"
msgstr "" msgstr ""

View File

@ -5,15 +5,15 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: unnamed project\n" "Project-Id-Version: unnamed project\n"
"PO-Revision-Date: 2025-02-27 14:27+0300\n" "PO-Revision-Date: 2025-03-09 17:31+0300\n"
"Last-Translator: Maxim Slipenko <maks1ms@alt-gnome.ru>\n" "Last-Translator: Maxim Slipenko <maks1ms@alt-gnome.ru>\n"
"Language-Team: Russian\n" "Language-Team: Russian\n"
"Language: ru\n" "Language: ru\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Gtranslator 47.1\n" "X-Generator: Gtranslator 47.1\n"
#: build.go:44 #: build.go:44
@ -25,8 +25,8 @@ msgid "Path to the build script"
msgstr "Путь к скрипту сборки" msgstr "Путь к скрипту сборки"
#: build.go:55 #: build.go:55
msgid "Specify package in script (for multi package script only)" msgid "Specify subpackage in script (for multi package script only)"
msgstr "Укажите пакет в скрипте (только для многопакетного скрипта)" msgstr "Укажите подпакет в скрипте (только для многопакетного скрипта)"
#: build.go:60 #: build.go:60
msgid "Name of the package to build and its repo (example: default/go-bin)" msgid "Name of the package to build and its repo (example: default/go-bin)"
@ -41,31 +41,31 @@ msgstr "Создайте пакет с нуля, даже если уже име
msgid "Error initialization database" msgid "Error initialization database"
msgstr "Ошибка инициализации базы данных" msgstr "Ошибка инициализации базы данных"
#: build.go:105 #: build.go:104
msgid "Package not found" msgid "Package not found"
msgstr "Пакет не найден" msgstr "Пакет не найден"
#: build.go:123 #: build.go:124
msgid "Error pulling repositories" msgid "Error pulling repositories"
msgstr "Ошибка при извлечении репозиториев" msgstr "Ошибка при извлечении репозиториев"
#: build.go:131 #: build.go:132
msgid "Unable to detect a supported package manager on the system" msgid "Unable to detect a supported package manager on the system"
msgstr "Не удалось обнаружить поддерживаемый менеджер пакетов в системе" msgstr "Не удалось обнаружить поддерживаемый менеджер пакетов в системе"
#: build.go:137 #: build.go:138
msgid "Error parsing os release" msgid "Error parsing os release"
msgstr "Ошибка при разборе файла выпуска операционной системы" msgstr "Ошибка при разборе файла выпуска операционной системы"
#: build.go:158 #: build.go:160
msgid "Error building package" msgid "Error building package"
msgstr "Ошибка при сборке пакета" msgstr "Ошибка при сборке пакета"
#: build.go:165 #: build.go:167
msgid "Error getting working directory" msgid "Error getting working directory"
msgstr "Ошибка при получении рабочего каталога" msgstr "Ошибка при получении рабочего каталога"
#: build.go:174 #: build.go:176
msgid "Error moving the package" msgid "Error moving the package"
msgstr "Ошибка при перемещении пакета" msgstr "Ошибка при перемещении пакета"
@ -165,15 +165,15 @@ msgstr "Установить новый пакет"
msgid "Command install expected at least 1 argument, got %d" msgid "Command install expected at least 1 argument, got %d"
msgstr "Для команды install ожидался хотя бы 1 аргумент, получено %d" msgstr "Для команды install ожидался хотя бы 1 аргумент, получено %d"
#: install.go:146 #: install.go:151
msgid "Remove an installed package" msgid "Remove an installed package"
msgstr "Удалить установленный пакет" msgstr "Удалить установленный пакет"
#: install.go:151 #: install.go:156
msgid "Command remove expected at least 1 argument, got %d" msgid "Command remove expected at least 1 argument, got %d"
msgstr "Для команды remove ожидался хотя бы 1 аргумент, получено %d" msgstr "Для команды remove ожидался хотя бы 1 аргумент, получено %d"
#: install.go:163 #: install.go:168
msgid "Error removing packages" msgid "Error removing packages"
msgstr "Ошибка при удалении пакетов" msgstr "Ошибка при удалении пакетов"
@ -335,11 +335,11 @@ msgstr "%s %s загружается — %s/с\n"
msgid "ERROR" msgid "ERROR"
msgstr "ОШИБКА" msgstr "ОШИБКА"
#: list.go:40 #: list.go:41
msgid "List ALR repo packages" msgid "List ALR repo packages"
msgstr "Список пакетов репозитория ALR" msgstr "Список пакетов репозитория ALR"
#: list.go:91 #: list.go:92
msgid "Error listing installed packages" msgid "Error listing installed packages"
msgstr "Ошибка при составлении списка установленных пакетов" msgstr "Ошибка при составлении списка установленных пакетов"
@ -371,27 +371,31 @@ msgstr "Показать справку"
msgid "Error while running app" msgid "Error while running app"
msgstr "Ошибка при запуске приложения" msgstr "Ошибка при запуске приложения"
#: pkg/build/build.go:153 #: pkg/build/build.go:156
msgid "Failed to prompt user to view build script" msgid "Failed to prompt user to view build script"
msgstr "Не удалось предложить пользователю просмотреть скрипт сборки" msgstr "Не удалось предложить пользователю просмотреть скрипт сборки"
#: pkg/build/build.go:157 #: pkg/build/build.go:160
msgid "Building package" msgid "Building package"
msgstr "Сборка пакета" msgstr "Сборка пакета"
#: pkg/build/build.go:228 #: pkg/build/build.go:208
msgid "The checksums array must be the same length as sources"
msgstr "Массив контрольных сумм должен быть той же длины, что и источники"
#: pkg/build/build.go:235
msgid "Downloading sources" msgid "Downloading sources"
msgstr "Скачивание источников" msgstr "Скачивание источников"
#: pkg/build/build.go:246 #: pkg/build/build.go:257
msgid "Building package metadata" msgid "Building package metadata"
msgstr "Сборка метаданных пакета" msgstr "Сборка метаданных пакета"
#: pkg/build/build.go:268 #: pkg/build/build.go:279
msgid "Compressing package" msgid "Compressing package"
msgstr "Сжатие пакета" msgstr "Сжатие пакета"
#: pkg/build/build.go:421 #: pkg/build/build.go:438
msgid "" msgid ""
"Your system's CPU architecture doesn't match this package. Do you want to " "Your system's CPU architecture doesn't match this package. Do you want to "
"build anyway?" "build anyway?"
@ -399,46 +403,52 @@ msgstr ""
"Архитектура процессора вашей системы не соответствует этому пакету. Вы все " "Архитектура процессора вашей системы не соответствует этому пакету. Вы все "
"равно хотите выполнить сборку?" "равно хотите выполнить сборку?"
#: pkg/build/build.go:435 #: pkg/build/build.go:452
msgid "This package is already installed" msgid "This package is already installed"
msgstr "Этот пакет уже установлен" msgstr "Этот пакет уже установлен"
#: pkg/build/build.go:459 #: pkg/build/build.go:476
msgid "Installing build dependencies" msgid "Installing build dependencies"
msgstr "Установка зависимостей сборки" msgstr "Установка зависимостей сборки"
#: pkg/build/build.go:500 #: pkg/build/build.go:517
msgid "Installing dependencies" msgid "Installing dependencies"
msgstr "Установка зависимостей" msgstr "Установка зависимостей"
#: pkg/build/build.go:535 #: pkg/build/build.go:598
msgid "The checksums array must be the same length as sources"
msgstr "Массив контрольных сумм должен быть той же длины, что и источники"
#: pkg/build/build.go:586
msgid "Would you like to remove the build dependencies?" msgid "Would you like to remove the build dependencies?"
msgstr "Хотели бы вы удалить зависимости сборки?" msgstr "Хотели бы вы удалить зависимости сборки?"
#: pkg/build/build.go:649 #: pkg/build/build.go:661
msgid "Executing prepare()" msgid "Executing prepare()"
msgstr "Исполнение prepare()" msgstr "Исполнение prepare()"
#: pkg/build/build.go:659 #: pkg/build/build.go:671
msgid "Executing build()" msgid "Executing build()"
msgstr "Исполнение build()" msgstr "Исполнение build()"
#: pkg/build/build.go:689 pkg/build/build.go:709 #: pkg/build/build.go:701 pkg/build/build.go:721
msgid "Executing %s()" msgid "Executing %s()"
msgstr "Исполнение %s()" msgstr "Исполнение %s()"
#: pkg/build/build.go:768 #: pkg/build/build.go:780
msgid "Error installing native packages" msgid "Error installing native packages"
msgstr "Ошибка при установке нативных пакетов" msgstr "Ошибка при установке нативных пакетов"
#: pkg/build/build.go:792 #: pkg/build/build.go:804
msgid "Error installing package" msgid "Error installing package"
msgstr "Ошибка при установке пакета" msgstr "Ошибка при установке пакета"
#: pkg/build/build.go:863
msgid "AutoProv is not implemented for this package format, so it's skipped"
msgstr ""
"AutoProv не реализовано для этого формата пакета, поэтому будет пропущено"
#: pkg/build/build.go:874
msgid "AutoReq is not implemented for this package format, so it's skipped"
msgstr ""
"AutoReq не реализовано для этого формата пакета, поэтому будет пропущено"
#: pkg/build/findDeps.go:35 #: pkg/build/findDeps.go:35
msgid "Command not found on the system" msgid "Command not found on the system"
msgstr "Команда не найдена в системе" msgstr "Команда не найдена в системе"
@ -451,16 +461,6 @@ msgstr "Найденная предоставленная зависимость
msgid "Required dependency found" msgid "Required dependency found"
msgstr "Найдена требуемая зависимость" msgstr "Найдена требуемая зависимость"
#: pkg/build/utils.go:133
msgid "AutoProv is not implemented for this package format, so it's skipped"
msgstr ""
"AutoProv не реализовано для этого формата пакета, поэтому будет пропущено"
#: pkg/build/utils.go:144
msgid "AutoReq is not implemented for this package format, so it's skipped"
msgstr ""
"AutoReq не реализовано для этого формата пакета, поэтому будет пропущено"
#: pkg/repos/pull.go:79 #: pkg/repos/pull.go:79
msgid "Pulling repository" msgid "Pulling repository"
msgstr "Скачивание репозитория" msgstr "Скачивание репозитория"

View File

@ -23,6 +23,7 @@ import "gitea.plemya-x.ru/Plemya-x/ALR/pkg/manager"
type BuildOpts struct { type BuildOpts struct {
Script string Script string
Repository string
Packages []string Packages []string
Manager manager.Manager Manager manager.Manager
Clean bool Clean bool
@ -102,6 +103,7 @@ type BuildVars struct {
Scripts Scripts `sh:"scripts"` Scripts Scripts `sh:"scripts"`
AutoReq []string `sh:"auto_req"` AutoReq []string `sh:"auto_req"`
AutoProv []string `sh:"auto_prov"` AutoProv []string `sh:"auto_prov"`
Base string
} }
type Scripts struct { type Scripts struct {

16
list.go
View File

@ -30,6 +30,7 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config" "gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
database "gitea.plemya-x.ru/Plemya-x/ALR/internal/db" database "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/build"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/manager" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/manager"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/repos" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/repos"
) )
@ -78,7 +79,7 @@ func ListCmd() *cli.Command {
} }
defer result.Close() defer result.Close()
var installed map[string]string installedAlrPackages := map[string]string{}
if c.Bool("installed") { if c.Bool("installed") {
mgr := manager.Detect() mgr := manager.Detect()
if mgr == nil { if mgr == nil {
@ -86,11 +87,20 @@ func ListCmd() *cli.Command {
os.Exit(1) os.Exit(1)
} }
installed, err = mgr.ListInstalled(&manager.Opts{AsRoot: false}) installed, err := mgr.ListInstalled(&manager.Opts{AsRoot: false})
if err != nil { if err != nil {
slog.Error(gotext.Get("Error listing installed packages"), "err", err) slog.Error(gotext.Get("Error listing installed packages"), "err", err)
os.Exit(1) os.Exit(1)
} }
for pkgName, version := range installed {
matches := build.RegexpALRPackageName.FindStringSubmatch(pkgName)
if matches != nil {
packageName := matches[build.RegexpALRPackageName.SubexpIndex("package")]
repoName := matches[build.RegexpALRPackageName.SubexpIndex("repo")]
installedAlrPackages[fmt.Sprintf("%s/%s", repoName, packageName)] = version
}
}
} }
for result.Next() { for result.Next() {
@ -106,7 +116,7 @@ func ListCmd() *cli.Command {
version := pkg.Version version := pkg.Version
if c.Bool("installed") { if c.Bool("installed") {
instVersion, ok := installed[pkg.Name] instVersion, ok := installedAlrPackages[fmt.Sprintf("%s/%s", pkg.Repository, pkg.Name)]
if !ok { if !ok {
continue continue
} else { } else {

View File

@ -28,6 +28,8 @@ import (
"log/slog" "log/slog"
"os" "os"
"path/filepath" "path/filepath"
"slices"
"strconv"
"strings" "strings"
"time" "time"
@ -87,6 +89,7 @@ func NewBuilder(
func (b *Builder) UpdateOptsFromPkg(pkg *db.Package, packages []string) { func (b *Builder) UpdateOptsFromPkg(pkg *db.Package, packages []string) {
repodir := b.config.GetPaths(b.ctx).RepoDir repodir := b.config.GetPaths(b.ctx).RepoDir
b.opts.Repository = pkg.Repository
if pkg.BasePkgName != "" { if pkg.BasePkgName != "" {
b.opts.Script = filepath.Join(repodir, pkg.Repository, pkg.BasePkgName, "alr.sh") b.opts.Script = filepath.Join(repodir, pkg.Repository, pkg.BasePkgName, "alr.sh")
b.opts.Packages = packages b.opts.Packages = packages
@ -108,7 +111,10 @@ func (b *Builder) BuildPackage(ctx context.Context) ([]string, []string, error)
return nil, nil, err return nil, nil, err
} }
dirs := b.getDirs(basePkg) dirs, err := b.getDirs(basePkg)
if err != nil {
return nil, nil, err
}
builtPaths := make([]string, 0) builtPaths := make([]string, 0)
@ -116,14 +122,11 @@ func (b *Builder) BuildPackage(ctx context.Context) ([]string, []string, error)
// возвращаем его, а не собираем заново. // возвращаем его, а не собираем заново.
if !b.opts.Clean { if !b.opts.Clean {
var remainingVars []*types.BuildVars var remainingVars []*types.BuildVars
for _, vars := range varsOfPackages { for _, vars := range varsOfPackages {
builtPkgPath, ok, err := checkForBuiltPackage( builtPkgPath, ok, err := b.checkForBuiltPackage(
b.opts.Manager,
vars, vars,
getPkgFormat(b.opts.Manager), getPkgFormat(b.opts.Manager),
dirs.BaseDir, dirs.BaseDir,
b.info,
) )
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
@ -200,8 +203,12 @@ func (b *Builder) BuildPackage(ctx context.Context) ([]string, []string, error)
buildDepends = removeDuplicates(buildDepends) buildDepends = removeDuplicates(buildDepends)
optDepends = removeDuplicates(optDepends) optDepends = removeDuplicates(optDepends)
depends = removeDuplicates(depends) depends = removeDuplicates(depends)
sources = removeDuplicates(sources)
checksums = removeDuplicates(checksums) if len(sources) != len(checksums) {
slog.Error(gotext.Get("The checksums array must be the same length as sources"))
os.Exit(1)
}
sources, checksums = removeDuplicatesSources(sources, checksums)
mergedVars := types.BuildVars{ mergedVars := types.BuildVars{
Sources: sources, Sources: sources,
@ -238,7 +245,11 @@ func (b *Builder) BuildPackage(ctx context.Context) ([]string, []string, error)
} }
for _, vars := range varsOfPackages { for _, vars := range varsOfPackages {
funcOut, err := b.executePackageFunctions(ctx, dec, dirs, vars.Name) packageName := ""
if vars.Base != "" {
packageName = vars.Name
}
funcOut, err := b.executePackageFunctions(ctx, dec, dirs, packageName)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -247,7 +258,7 @@ func (b *Builder) BuildPackage(ctx context.Context) ([]string, []string, error)
pkgFormat := getPkgFormat(b.opts.Manager) // Получаем формат пакета pkgFormat := getPkgFormat(b.opts.Manager) // Получаем формат пакета
pkgInfo, err := buildPkgMetadata(ctx, vars, dirs, pkgFormat, b.info, append(repoDeps, builtNames...), funcOut.Contents) // Собираем метаданные пакета pkgInfo, err := b.buildPkgMetadata(ctx, vars, dirs, pkgFormat, append(repoDeps, builtNames...), funcOut.Contents) // Собираем метаданные пакета
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -366,6 +377,7 @@ func (b *Builder) executeFirstPass(
} }
vars := preVars.ToBuildVars() vars := preVars.ToBuildVars()
vars.Name = pkgName vars.Name = pkgName
vars.Base = pkgs.BasePkgName
varsOfPackages = append(varsOfPackages, &vars) varsOfPackages = append(varsOfPackages, &vars)
} }
@ -374,14 +386,19 @@ func (b *Builder) executeFirstPass(
} }
// Функция getDirs возвращает соответствующие директории для скрипта // Функция getDirs возвращает соответствующие директории для скрипта
func (b *Builder) getDirs(basePkg string) types.Directories { func (b *Builder) getDirs(basePkg string) (types.Directories, error) {
scriptPath, err := filepath.Abs(b.opts.Script)
if err != nil {
return types.Directories{}, err
}
baseDir := filepath.Join(b.config.GetPaths(b.ctx).PkgsDir, basePkg) // Определяем базовую директорию baseDir := filepath.Join(b.config.GetPaths(b.ctx).PkgsDir, basePkg) // Определяем базовую директорию
return types.Directories{ return types.Directories{
BaseDir: baseDir, BaseDir: baseDir,
SrcDir: filepath.Join(baseDir, "src"), SrcDir: filepath.Join(baseDir, "src"),
PkgDir: filepath.Join(baseDir, "pkg"), PkgDir: filepath.Join(baseDir, "pkg"),
ScriptDir: filepath.Dir(b.opts.Script), ScriptDir: filepath.Dir(scriptPath),
} }, nil
} }
// Функция executeSecondPass выполняет скрипт сборки второй раз без каких-либо ограничений. Возвращается декодер, // Функция executeSecondPass выполняет скрипт сборки второй раз без каких-либо ограничений. Возвращается декодер,
@ -531,11 +548,6 @@ func (b *Builder) buildALRDeps(ctx context.Context, depends []string) (builtPath
} }
func (b *Builder) getSources(ctx context.Context, dirs types.Directories, bv *types.BuildVars) error { func (b *Builder) getSources(ctx context.Context, dirs types.Directories, bv *types.BuildVars) error {
if len(bv.Sources) != len(bv.Checksums) {
slog.Error(gotext.Get("The checksums array must be the same length as sources"))
os.Exit(1)
}
for i, src := range bv.Sources { for i, src := range bv.Sources {
opts := dl.Options{ opts := dl.Options{
Name: fmt.Sprintf("%s[%d]", bv.Name, i), Name: fmt.Sprintf("%s[%d]", bv.Name, i),
@ -678,8 +690,8 @@ func (b *Builder) executePackageFunctions(
var filesFuncName string var filesFuncName string
if packageName == "" { if packageName == "" {
filesFuncName = "files"
packageFuncName = "package" packageFuncName = "package"
filesFuncName = "files"
} else { } else {
packageFuncName = fmt.Sprintf("package_%s", packageName) packageFuncName = fmt.Sprintf("package_%s", packageName)
filesFuncName = fmt.Sprintf("files_%s", packageName) filesFuncName = fmt.Sprintf("files_%s", packageName)
@ -795,3 +807,108 @@ func (b *Builder) InstallALRPackages(ctx context.Context, pkgs []db.Package, opt
} }
} }
} }
// Функция buildPkgMetadata создает метаданные для пакета, который будет собран.
func (b *Builder) buildPkgMetadata(
ctx context.Context,
vars *types.BuildVars,
dirs types.Directories,
pkgFormat string,
deps []string,
preferedContents *[]string,
) (*nfpm.Info, error) {
pkgInfo := getBasePkgInfo(vars, b.info, &b.opts)
pkgInfo.Description = vars.Description
pkgInfo.Platform = "linux"
pkgInfo.Homepage = vars.Homepage
pkgInfo.License = strings.Join(vars.Licenses, ", ")
pkgInfo.Maintainer = vars.Maintainer
pkgInfo.Overridables = nfpm.Overridables{
Conflicts: append(vars.Conflicts, vars.Name),
Replaces: vars.Replaces,
Provides: append(vars.Provides, vars.Name),
Depends: deps,
}
if pkgFormat == "apk" {
// Alpine отказывается устанавливать пакеты, которые предоставляют сами себя, поэтому удаляем такие элементы
pkgInfo.Overridables.Provides = slices.DeleteFunc(pkgInfo.Overridables.Provides, func(s string) bool {
return s == pkgInfo.Name
})
}
if vars.Epoch != 0 {
pkgInfo.Epoch = strconv.FormatUint(uint64(vars.Epoch), 10)
}
setScripts(vars, pkgInfo, dirs.ScriptDir)
if slices.Contains(vars.Architectures, "all") {
pkgInfo.Arch = "all"
}
contents, err := buildContents(vars, dirs, preferedContents)
if err != nil {
return nil, err
}
pkgInfo.Overridables.Contents = contents
if len(vars.AutoProv) == 1 && decoder.IsTruthy(vars.AutoProv[0]) {
if pkgFormat == "rpm" {
err = rpmFindProvides(ctx, pkgInfo, dirs)
if err != nil {
return nil, err
}
} else {
slog.Info(gotext.Get("AutoProv is not implemented for this package format, so it's skipped"))
}
}
if len(vars.AutoReq) == 1 && decoder.IsTruthy(vars.AutoReq[0]) {
if pkgFormat == "rpm" {
err = rpmFindRequires(ctx, pkgInfo, dirs)
if err != nil {
return nil, err
}
} else {
slog.Info(gotext.Get("AutoReq is not implemented for this package format, so it's skipped"))
}
}
return pkgInfo, nil
}
// Функция checkForBuiltPackage пытается обнаружить ранее собранный пакет и вернуть его путь
// и true, если нашла. Если нет, возвратит "", false, nil.
func (b *Builder) checkForBuiltPackage(
vars *types.BuildVars,
pkgFormat,
baseDir string,
) (string, bool, error) {
filename, err := b.pkgFileName(vars, pkgFormat)
if err != nil {
return "", false, err
}
pkgPath := filepath.Join(baseDir, filename)
_, err = os.Stat(pkgPath)
if err != nil {
return "", false, nil
}
return pkgPath, true, nil
}
// pkgFileName returns the filename of the package if it were to be built.
// This is used to check if the package has already been built.
func (b *Builder) pkgFileName(vars *types.BuildVars, pkgFormat string) (string, error) {
pkgInfo := getBasePkgInfo(vars, b.info, &b.opts)
packager, err := nfpm.Get(pkgFormat)
if err != nil {
return "", err
}
return packager.ConventionalFileName(pkgInfo), nil
}

View File

@ -17,11 +17,11 @@
package build package build
import ( import (
"context" "fmt"
"io" "io"
"log/slog"
"os" "os"
"path/filepath" "path/filepath"
"regexp"
"runtime" "runtime"
"slices" "slices"
"strconv" "strconv"
@ -33,7 +33,6 @@ import (
_ "github.com/goreleaser/nfpm/v2/arch" _ "github.com/goreleaser/nfpm/v2/arch"
_ "github.com/goreleaser/nfpm/v2/deb" _ "github.com/goreleaser/nfpm/v2/deb"
_ "github.com/goreleaser/nfpm/v2/rpm" _ "github.com/goreleaser/nfpm/v2/rpm"
"github.com/leonelquinteros/gotext"
"mvdan.cc/sh/v3/syntax" "mvdan.cc/sh/v3/syntax"
"github.com/goreleaser/nfpm/v2" "github.com/goreleaser/nfpm/v2"
@ -42,7 +41,6 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cpu" "gitea.plemya-x.ru/Plemya-x/ALR/internal/cpu"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/db" "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/overrides" "gitea.plemya-x.ru/Plemya-x/ALR/internal/overrides"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/decoder"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" "gitea.plemya-x.ru/Plemya-x/ALR/internal/types"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/manager" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/manager"
@ -77,77 +75,6 @@ func prepareDirs(dirs types.Directories) error {
return os.MkdirAll(dirs.PkgDir, 0o755) // Создаем директорию для пакетов return os.MkdirAll(dirs.PkgDir, 0o755) // Создаем директорию для пакетов
} }
// Функция buildPkgMetadata создает метаданные для пакета, который будет собран.
func buildPkgMetadata(
ctx context.Context,
vars *types.BuildVars,
dirs types.Directories,
pkgFormat string,
info *distro.OSRelease,
deps []string,
preferedContents *[]string,
) (*nfpm.Info, error) {
pkgInfo := getBasePkgInfo(vars, info)
pkgInfo.Description = vars.Description
pkgInfo.Platform = "linux"
pkgInfo.Homepage = vars.Homepage
pkgInfo.License = strings.Join(vars.Licenses, ", ")
pkgInfo.Maintainer = vars.Maintainer
pkgInfo.Overridables = nfpm.Overridables{
Conflicts: vars.Conflicts,
Replaces: vars.Replaces,
Provides: vars.Provides,
Depends: deps,
}
if pkgFormat == "apk" {
// Alpine отказывается устанавливать пакеты, которые предоставляют сами себя, поэтому удаляем такие элементы
pkgInfo.Overridables.Provides = slices.DeleteFunc(pkgInfo.Overridables.Provides, func(s string) bool {
return s == pkgInfo.Name
})
}
if vars.Epoch != 0 {
pkgInfo.Epoch = strconv.FormatUint(uint64(vars.Epoch), 10)
}
setScripts(vars, pkgInfo, dirs.ScriptDir)
if slices.Contains(vars.Architectures, "all") {
pkgInfo.Arch = "all"
}
contents, err := buildContents(vars, dirs, preferedContents)
if err != nil {
return nil, err
}
pkgInfo.Overridables.Contents = contents
if len(vars.AutoProv) == 1 && decoder.IsTruthy(vars.AutoProv[0]) {
if pkgFormat == "rpm" {
err = rpmFindProvides(ctx, pkgInfo, dirs)
if err != nil {
return nil, err
}
} else {
slog.Info(gotext.Get("AutoProv is not implemented for this package format, so it's skipped"))
}
}
if len(vars.AutoReq) == 1 && decoder.IsTruthy(vars.AutoReq[0]) {
if pkgFormat == "rpm" {
err = rpmFindRequires(ctx, pkgInfo, dirs)
if err != nil {
return nil, err
}
} else {
slog.Info(gotext.Get("AutoReq is not implemented for this package format, so it's skipped"))
}
}
return pkgInfo, nil
}
// Функция buildContents создает секцию содержимого пакета, которая содержит файлы, // Функция buildContents создает секцию содержимого пакета, которая содержит файлы,
// которые будут включены в конечный пакет. // которые будут включены в конечный пакет.
func buildContents(vars *types.BuildVars, dirs types.Directories, preferedContents *[]string) ([]*files.Content, error) { func buildContents(vars *types.BuildVars, dirs types.Directories, preferedContents *[]string) ([]*files.Content, error) {
@ -244,33 +171,11 @@ func buildContents(vars *types.BuildVars, dirs types.Directories, preferedConten
return contents, nil return contents, nil
} }
// Функция checkForBuiltPackage пытается обнаружить ранее собранный пакет и вернуть его путь var RegexpALRPackageName = regexp.MustCompile(`^(?P<package>[^+]+)\+alr-(?P<repo>.+)$`)
// и true, если нашла. Если нет, возвратит "", false, nil.
func checkForBuiltPackage(
mgr manager.Manager,
vars *types.BuildVars,
pkgFormat,
baseDir string,
info *distro.OSRelease,
) (string, bool, error) {
filename, err := pkgFileName(vars, pkgFormat, info)
if err != nil {
return "", false, err
}
pkgPath := filepath.Join(baseDir, filename) func getBasePkgInfo(vars *types.BuildVars, info *distro.OSRelease, opts *types.BuildOpts) *nfpm.Info {
_, err = os.Stat(pkgPath)
if err != nil {
return "", false, nil
}
return pkgPath, true, nil
}
func getBasePkgInfo(vars *types.BuildVars, info *distro.OSRelease) *nfpm.Info {
return &nfpm.Info{ return &nfpm.Info{
Name: vars.Name, Name: fmt.Sprintf("%s+alr-%s", vars.Name, opts.Repository),
Arch: cpu.Arch(), Arch: cpu.Arch(),
Version: vars.Version, Version: vars.Version,
Release: overrides.ReleasePlatformSpecific(vars.Release, info), Release: overrides.ReleasePlatformSpecific(vars.Release, info),
@ -278,19 +183,6 @@ func getBasePkgInfo(vars *types.BuildVars, info *distro.OSRelease) *nfpm.Info {
} }
} }
// pkgFileName returns the filename of the package if it were to be built.
// This is used to check if the package has already been built.
func pkgFileName(vars *types.BuildVars, pkgFormat string, info *distro.OSRelease) (string, error) {
pkgInfo := getBasePkgInfo(vars, info)
packager, err := nfpm.Get(pkgFormat)
if err != nil {
return "", err
}
return packager.ConventionalFileName(pkgInfo), nil
}
// Функция getPkgFormat возвращает формат пакета из менеджера пакетов, // Функция getPkgFormat возвращает формат пакета из менеджера пакетов,
// или ALR_PKG_FORMAT, если он установлен. // или ALR_PKG_FORMAT, если он установлен.
func getPkgFormat(mgr manager.Manager) string { func getPkgFormat(mgr manager.Manager) string {
@ -421,3 +313,24 @@ func removeDuplicates(slice []string) []string {
return result return result
} }
func removeDuplicatesSources(sources, checksums []string) ([]string, []string) {
seen := map[string]string{}
keys := make([]string, 0)
for i, s := range sources {
if val, ok := seen[s]; !ok || strings.EqualFold(val, "SKIP") {
if !ok {
keys = append(keys, s)
}
seen[s] = checksums[i]
}
}
newSources := make([]string, len(keys))
newChecksums := make([]string, len(keys))
for i, k := range keys {
newSources[i] = k
newChecksums[i] = seen[k]
}
return newSources, newChecksums
}

View File

@ -0,0 +1,47 @@
// ALR - Any Linux Repository
// Copyright (C) 2025 Евгений Храмов
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package build
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestRemoveDuplicatesSources(t *testing.T) {
type testCase struct {
Name string
Sources []string
Checksums []string
NewSources []string
NewChecksums []string
}
for _, tc := range []testCase{{
Name: "prefer non-skip values",
Sources: []string{"a", "b", "c", "a"},
Checksums: []string{"skip", "skip", "skip", "1"},
NewSources: []string{"a", "b", "c"},
NewChecksums: []string{"1", "skip", "skip"},
}} {
t.Run(tc.Name, func(t *testing.T) {
s, c := removeDuplicatesSources(tc.Sources, tc.Checksums)
assert.Equal(t, s, tc.NewSources)
assert.Equal(t, c, tc.NewChecksums)
})
}
}

View File

@ -32,19 +32,19 @@ deps=("python3")
deps_arch=("python") deps_arch=("python")
deps_alpine=("python3") deps_alpine=("python3")
build_deps=("python3" "python3-setuptools") build_deps=("python3" "python3-pip")
build_deps_arch=("python" "python-setuptools") build_deps_arch=("python" "python-pip")
build_deps_alpine=("python3" "py3-setuptools") build_deps_alpine=("python3" "py3-pip")
sources=("https://files.pythonhosted.org/packages/source/{{.SourceURL.Filename | firstchar}}/{{.Info.Name}}/{{.SourceURL.Filename}}") sources=("https://files.pythonhosted.org/packages/source/{{.SourceURL.Filename | firstchar}}/{{.Info.Name}}/{{.SourceURL.Filename}}")
checksums=('blake2b-256:{{.SourceURL.Digests.blake2b_256}}') checksums=('blake2b-256:{{.SourceURL.Digests.blake2b_256}}')
build() { build() {
cd "$srcdir/{{.Info.Name}}-${version}" cd "$srcdir/{{.Info.Name}}-${version}"
python3 setup.py build python3 -m build
} }
package() { package() {
cd "$srcdir/{{.Info.Name}}-${version}" cd "$srcdir/{{.Info.Name}}-${version}"
python3 setup.py install --root="${pkgdir}/" --optimize=1 || return 1 pip install --root="${pkgdir}/" . --no-deps --disable-pip-version-check
} }

View File

@ -83,7 +83,7 @@ func AddRepoCmd() *cli.Command {
os.Exit(1) os.Exit(1)
} }
err = toml.NewEncoder(cfgFl).Encode(cfg) err = cfg.Save(cfgFl)
if err != nil { if err != nil {
slog.Error(gotext.Get("Error encoding config"), "err", err) slog.Error(gotext.Get("Error encoding config"), "err", err)
os.Exit(1) os.Exit(1)

View File

@ -29,7 +29,6 @@ import (
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"go.elara.ws/vercmp" "go.elara.ws/vercmp"
"golang.org/x/exp/maps" "golang.org/x/exp/maps"
"golang.org/x/exp/slices"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/config" "gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
database "gitea.plemya-x.ru/Plemya-x/ALR/internal/db" database "gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
@ -39,6 +38,7 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/manager" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/manager"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/repos" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/repos"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/search"
) )
func UpgradeCmd() *cli.Command { func UpgradeCmd() *cli.Command {
@ -85,7 +85,7 @@ func UpgradeCmd() *cli.Command {
} }
} }
updates, err := checkForUpdates(ctx, mgr, cfg, rs, info) updates, err := checkForUpdates(ctx, mgr, cfg, db, rs, info)
if err != nil { if err != nil {
slog.Error(gotext.Get("Error checking for updates"), "err", err) slog.Error(gotext.Get("Error checking for updates"), "err", err)
os.Exit(1) os.Exit(1)
@ -121,6 +121,7 @@ func checkForUpdates(
ctx context.Context, ctx context.Context,
mgr manager.Manager, mgr manager.Manager,
cfg *config.ALRConfig, cfg *config.ALRConfig,
db *database.Database,
rs *repos.Repos, rs *repos.Repos,
info *distro.OSRelease, info *distro.OSRelease,
) ([]database.Package, error) { ) ([]database.Package, error) {
@ -130,25 +131,27 @@ func checkForUpdates(
} }
pkgNames := maps.Keys(installed) pkgNames := maps.Keys(installed)
found, _, err := rs.FindPkgs(ctx, pkgNames)
s := search.New(db)
var out []database.Package
for _, pkgName := range pkgNames {
matches := build.RegexpALRPackageName.FindStringSubmatch(pkgName)
if matches != nil {
packageName := matches[build.RegexpALRPackageName.SubexpIndex("package")]
repoName := matches[build.RegexpALRPackageName.SubexpIndex("repo")]
pkgs, err := s.Search(
ctx,
search.NewSearchOptions().
WithName(packageName).
WithRepository(repoName).
Build(),
)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var out []database.Package
for pkgName, pkgs := range found {
if slices.Contains(cfg.IgnorePkgUpdates(ctx), pkgName) {
continue
}
if len(pkgs) > 1 {
// Puts the element with the highest version first
slices.SortFunc(pkgs, func(a, b database.Package) int {
return vercmp.Compare(a.Version, b.Version)
})
}
// First element is the package we want to install
pkg := pkgs[0] pkg := pkgs[0]
repoVer := pkg.Version repoVer := pkg.Version
@ -167,5 +170,8 @@ func checkForUpdates(
out = append(out, pkg) out = append(out, pkg)
} }
} }
}
return out, nil return out, nil
} }