ALR/build.go
2025-04-14 23:35:10 +03:00

204 lines
5.4 KiB
Go

// This file was originally part of the project "LURE - Linux User REpository", created by Elara Musayelyan.
// It has been modified as part of "ALR - Any Linux Repository" by Евгений Храмов.
//
// 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 main
import (
"log/slog"
"os"
"path/filepath"
"strings"
"github.com/leonelquinteros/gotext"
"github.com/urfave/cli/v2"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils"
appbuilder "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils/app_builder"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/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/build"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/manager"
)
func BuildCmd() *cli.Command {
return &cli.Command{
Name: "build",
Usage: gotext.Get("Build a local package"),
Flags: []cli.Flag{
&cli.StringFlag{
Name: "script",
Aliases: []string{"s"},
Value: "alr.sh",
Usage: gotext.Get("Path to the build script"),
},
&cli.StringFlag{
Name: "subpackage",
Aliases: []string{"sb"},
Usage: gotext.Get("Specify subpackage in script (for multi package script only)"),
},
&cli.StringFlag{
Name: "package",
Aliases: []string{"p"},
Usage: gotext.Get("Name of the package to build and its repo (example: default/go-bin)"),
},
&cli.BoolFlag{
Name: "clean",
Aliases: []string{"c"},
Usage: gotext.Get("Build package from scratch even if there's an already built package available"),
},
},
Action: func(c *cli.Context) error {
wd, err := os.Getwd()
if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error getting working directory"), err)
}
wd, cleanup, err := Mount(wd)
if err != nil {
return err
}
defer cleanup()
ctx := c.Context
deps, err := appbuilder.
New(ctx).
WithConfig().
WithDB().
WithReposNoPull().
Build()
if err != nil {
return cli.Exit(err, 1)
}
defer deps.Defer()
var script string
var packages []string
// Обнаружение менеджера пакетов
mgr := manager.Detect()
if mgr == nil {
slog.Error(gotext.Get("Unable to detect a supported package manager on the system"))
os.Exit(1)
}
info, err := distro.ParseOSRelease(ctx)
if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error parsing os release"), err)
}
if err := utils.ExitIfCantDropCapsToAlrUser(); err != nil {
return err
}
builder, err := build.NewMainBuilder(
deps.Cfg,
deps.Repos,
)
if err != nil {
return err
}
var res *build.BuildResult
switch {
case c.IsSet("script"):
script = c.String("script")
packages = append(packages, c.String("script-package"))
res, err = builder.BuildPackageFromScript(
ctx,
&build.BuildPackageFromScriptArgs{
Script: script,
Packages: packages,
BuildArgs: build.BuildArgs{
Opts: &types.BuildOpts{
Clean: c.Bool("clean"),
Interactive: c.Bool("interactive"),
},
PkgFormat_: build.GetPkgFormat(mgr),
Info: info,
},
},
)
if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error building package"), err)
}
case c.IsSet("package"):
// TODO: handle multiple packages
packageInput := c.String("package")
arr := strings.Split(packageInput, "/")
var packageSearch string
if len(arr) == 2 {
packageSearch = arr[1]
} else {
packageSearch = arr[0]
}
pkgs, _, _ := deps.Repos.FindPkgs(ctx, []string{packageSearch})
pkg, ok := pkgs[packageSearch]
if len(pkg) < 1 || !ok {
slog.Error(gotext.Get("Package not found"))
os.Exit(1)
}
if pkg[0].BasePkgName != "" {
packages = append(packages, pkg[0].Name)
}
res, err = builder.BuildPackageFromDb(
ctx,
&build.BuildPackageFromDbArgs{
Package: &pkg[0],
Packages: packages,
BuildArgs: build.BuildArgs{
Opts: &types.BuildOpts{
Clean: c.Bool("clean"),
Interactive: c.Bool("interactive"),
},
PkgFormat_: build.GetPkgFormat(mgr),
Info: info,
},
},
)
if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error building package"), err)
}
default:
slog.Error(gotext.Get("Nothing to build"))
os.Exit(1)
}
// Перемещение собранных пакетов в рабочую директорию
for _, pkgPath := range res.PackagePaths {
name := filepath.Base(pkgPath)
err = osutils.Move(pkgPath, filepath.Join(wd, name))
if err != nil {
return cliutils.FormatCliExit(gotext.Get("Error moving the package"), err)
}
}
return nil
},
}
}