chore: make usage strings translatable

This commit is contained in:
Maxim Slipenko 2025-01-22 17:16:15 +03:00
parent b9bf908007
commit 30f95a4cbf
12 changed files with 789 additions and 584 deletions

126
build.go

@ -35,73 +35,75 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/repos" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/repos"
) )
var buildCmd = &cli.Command{ func BuildCmd() *cli.Command {
Name: "build", return &cli.Command{
Usage: "Build a local package", Name: "build",
Flags: []cli.Flag{ Usage: gotext.Get("Build a local package"),
&cli.StringFlag{ Flags: []cli.Flag{
Name: "script", &cli.StringFlag{
Aliases: []string{"s"}, Name: "script",
Value: "alr.sh", Aliases: []string{"s"},
Usage: "Path to the build script", Value: "alr.sh",
Usage: gotext.Get("Path to the build script"),
},
&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"),
},
}, },
&cli.StringFlag{ Action: func(c *cli.Context) error {
Name: "package", ctx := c.Context
Aliases: []string{"p"},
Usage: "Name of the package to build and its repo (example: default/go-bin)",
},
&cli.BoolFlag{
Name: "clean",
Aliases: []string{"c"},
Usage: "Build package from scratch even if there's an already built package available",
},
},
Action: func(c *cli.Context) error {
ctx := c.Context
script := c.String("script") script := c.String("script")
if c.String("package") != "" { if c.String("package") != "" {
script = filepath.Join(config.GetPaths(ctx).RepoDir, c.String("package"), "alr.sh") script = filepath.Join(config.GetPaths(ctx).RepoDir, c.String("package"), "alr.sh")
} }
err := repos.Pull(ctx, config.Config(ctx).Repos) err := repos.Pull(ctx, config.Config(ctx).Repos)
if err != nil {
slog.Error(gotext.Get("Error pulling repositories"), "err", err)
os.Exit(1)
}
mgr := manager.Detect()
if mgr == nil {
slog.Error(gotext.Get("Unable to detect a supported package manager on the system"))
os.Exit(1)
}
pkgPaths, _, err := build.BuildPackage(ctx, types.BuildOpts{
Script: script,
Manager: mgr,
Clean: c.Bool("clean"),
Interactive: c.Bool("interactive"),
})
if err != nil {
slog.Error(gotext.Get("Error building package"), "err", err)
os.Exit(1)
}
wd, err := os.Getwd()
if err != nil {
slog.Error(gotext.Get("Error getting working directory"), "err", err)
os.Exit(1)
}
for _, pkgPath := range pkgPaths {
name := filepath.Base(pkgPath)
err = osutils.Move(pkgPath, filepath.Join(wd, name))
if err != nil { if err != nil {
slog.Error(gotext.Get("Error moving the package"), "err", err) slog.Error(gotext.Get("Error pulling repositories"), "err", err)
os.Exit(1) os.Exit(1)
} }
}
return nil mgr := manager.Detect()
}, if mgr == nil {
slog.Error(gotext.Get("Unable to detect a supported package manager on the system"))
os.Exit(1)
}
pkgPaths, _, err := build.BuildPackage(ctx, types.BuildOpts{
Script: script,
Manager: mgr,
Clean: c.Bool("clean"),
Interactive: c.Bool("interactive"),
})
if err != nil {
slog.Error(gotext.Get("Error building package"), "err", err)
os.Exit(1)
}
wd, err := os.Getwd()
if err != nil {
slog.Error(gotext.Get("Error getting working directory"), "err", err)
os.Exit(1)
}
for _, pkgPath := range pkgPaths {
name := filepath.Base(pkgPath)
err = osutils.Move(pkgPath, filepath.Join(wd, name))
if err != nil {
slog.Error(gotext.Get("Error moving the package"), "err", err)
os.Exit(1)
}
}
return nil
},
}
} }

56
fix.go

@ -31,39 +31,41 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/repos" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/repos"
) )
var fixCmd = &cli.Command{ func FixCmd() *cli.Command {
Name: "fix", return &cli.Command{
Usage: "Attempt to fix problems with ALR", Name: "fix",
Action: func(c *cli.Context) error { Usage: gotext.Get("Attempt to fix problems with ALR"),
ctx := c.Context Action: func(c *cli.Context) error {
ctx := c.Context
db.Close() db.Close()
paths := config.GetPaths(ctx) paths := config.GetPaths(ctx)
slog.Info(gotext.Get("Removing cache directory")) slog.Info(gotext.Get("Removing cache directory"))
err := os.RemoveAll(paths.CacheDir) err := os.RemoveAll(paths.CacheDir)
if err != nil { if err != nil {
slog.Error(gotext.Get("Unable to remove cache directory"), "err", err) slog.Error(gotext.Get("Unable to remove cache directory"), "err", err)
os.Exit(1) os.Exit(1)
} }
slog.Info(gotext.Get("Rebuilding cache")) slog.Info(gotext.Get("Rebuilding cache"))
err = os.MkdirAll(paths.CacheDir, 0o755) err = os.MkdirAll(paths.CacheDir, 0o755)
if err != nil { if err != nil {
slog.Error(gotext.Get("Unable to create new cache directory"), "err", err) slog.Error(gotext.Get("Unable to create new cache directory"), "err", err)
os.Exit(1) os.Exit(1)
} }
err = repos.Pull(ctx, config.Config(ctx).Repos) err = repos.Pull(ctx, config.Config(ctx).Repos)
if err != nil { if err != nil {
slog.Error(gotext.Get("Error pulling repos"), "err", err) slog.Error(gotext.Get("Error pulling repos"), "err", err)
os.Exit(1) os.Exit(1)
} }
slog.Info(gotext.Get("Done")) slog.Info(gotext.Get("Done"))
return nil return nil
}, },
}
} }

71
gen.go

@ -22,44 +22,45 @@ package main
import ( import (
"os" "os"
"github.com/leonelquinteros/gotext"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/gen" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/gen"
) )
var genCmd = &cli.Command{ func GenCmd() *cli.Command {
Name: "generate", return &cli.Command{
Usage: "Generate a ALR script from a template", Name: "generate",
Aliases: []string{"gen"}, Usage: gotext.Get("Generate a ALR script from a template"),
Subcommands: []*cli.Command{ Aliases: []string{"gen"},
genPipCmd, Subcommands: []*cli.Command{
}, &cli.Command{
} Name: "pip",
Usage: gotext.Get("Generate a ALR script for a pip module"),
var genPipCmd = &cli.Command{ Flags: []cli.Flag{
Name: "pip", &cli.StringFlag{
Usage: "Generate a ALR script for a pip module", Name: "name",
Flags: []cli.Flag{ Aliases: []string{"n"},
&cli.StringFlag{ Required: true,
Name: "name", },
Aliases: []string{"n"}, &cli.StringFlag{
Required: true, Name: "version",
}, Aliases: []string{"v"},
&cli.StringFlag{ Required: true,
Name: "version", },
Aliases: []string{"v"}, &cli.StringFlag{
Required: true, Name: "description",
}, Aliases: []string{"d"},
&cli.StringFlag{ },
Name: "description", },
Aliases: []string{"d"}, Action: func(c *cli.Context) error {
}, return gen.Pip(os.Stdout, gen.PipOptions{
}, Name: c.String("name"),
Action: func(c *cli.Context) error { Version: c.String("version"),
return gen.Pip(os.Stdout, gen.PipOptions{ Description: c.String("description"),
Name: c.String("name"), })
Version: c.String("version"), },
Description: c.String("description"), },
}) },
}, }
} }

130
helper.go

@ -35,75 +35,77 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro"
) )
var helperCmd = &cli.Command{ func HelperCmd() *cli.Command {
Name: "helper", var helperListCmd = &cli.Command{
Usage: "Run a ALR helper command", Name: "list",
ArgsUsage: `<helper_name|"list">`, Usage: gotext.Get("List all the available helper commands"),
Subcommands: []*cli.Command{helperListCmd}, Aliases: []string{"ls"},
Flags: []cli.Flag{ Action: func(ctx *cli.Context) error {
&cli.StringFlag{ for name := range helpers.Helpers {
Name: "dest-dir", fmt.Println(name)
Aliases: []string{"d"}, }
Usage: "The directory that the install commands will install to", return nil
Value: "dest",
}, },
}, }
Action: func(c *cli.Context) error {
ctx := c.Context
if c.Args().Len() < 1 { return &cli.Command{
cli.ShowSubcommandHelpAndExit(c, 1) Name: "helper",
} Usage: gotext.Get("Run a ALR helper command"),
ArgsUsage: `<helper_name|"list">`,
Subcommands: []*cli.Command{helperListCmd},
Flags: []cli.Flag{
&cli.StringFlag{
Name: "dest-dir",
Aliases: []string{"d"},
Usage: gotext.Get("The directory that the install commands will install to"),
Value: "dest",
},
},
Action: func(c *cli.Context) error {
ctx := c.Context
helper, ok := helpers.Helpers[c.Args().First()] if c.Args().Len() < 1 {
if !ok { cli.ShowSubcommandHelpAndExit(c, 1)
slog.Error(gotext.Get("No such helper command"), "name", c.Args().First()) }
os.Exit(1)
}
wd, err := os.Getwd() helper, ok := helpers.Helpers[c.Args().First()]
if err != nil { if !ok {
slog.Error(gotext.Get("Error getting working directory"), "err", err) slog.Error(gotext.Get("No such helper command"), "name", c.Args().First())
os.Exit(1) os.Exit(1)
} }
info, err := distro.ParseOSRelease(ctx) wd, err := os.Getwd()
if err != nil { if err != nil {
slog.Error(gotext.Get("Error getting working directory"), "err", err) slog.Error(gotext.Get("Error getting working directory"), "err", err)
os.Exit(1) os.Exit(1)
} }
hc := interp.HandlerContext{ info, err := distro.ParseOSRelease(ctx)
Env: expand.ListEnviron( if err != nil {
"pkgdir="+c.String("dest-dir"), slog.Error(gotext.Get("Error getting working directory"), "err", err)
"DISTRO_ID="+info.ID, os.Exit(1)
"DISTRO_ID_LIKE="+strings.Join(info.Like, " "), }
"ARCH="+cpu.Arch(),
),
Dir: wd,
Stdin: os.Stdin,
Stdout: os.Stdout,
Stderr: os.Stderr,
}
return helper(hc, c.Args().First(), c.Args().Slice()[1:]) hc := interp.HandlerContext{
}, Env: expand.ListEnviron(
CustomHelpTemplate: cli.CommandHelpTemplate, "pkgdir="+c.String("dest-dir"),
BashComplete: func(ctx *cli.Context) { "DISTRO_ID="+info.ID,
for name := range helpers.Helpers { "DISTRO_ID_LIKE="+strings.Join(info.Like, " "),
fmt.Println(name) "ARCH="+cpu.Arch(),
} ),
}, Dir: wd,
} Stdin: os.Stdin,
Stdout: os.Stdout,
var helperListCmd = &cli.Command{ Stderr: os.Stderr,
Name: "list", }
Usage: "List all the available helper commands",
Aliases: []string{"ls"}, return helper(hc, c.Args().First(), c.Args().Slice()[1:])
Action: func(ctx *cli.Context) error { },
for name := range helpers.Helpers { CustomHelpTemplate: cli.CommandHelpTemplate,
fmt.Println(name) BashComplete: func(ctx *cli.Context) {
} for name := range helpers.Helpers {
return nil fmt.Println(name)
}, }
},
}
} }

@ -36,7 +36,7 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/repos" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/repos"
) )
func GetInfoCmd() *cli.Command { func InfoCmd() *cli.Command {
return &cli.Command{ return &cli.Command{
Name: "info", Name: "info",
Usage: gotext.Get("Print information about a package"), Usage: gotext.Get("Print information about a package"),

@ -36,96 +36,101 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/repos" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/repos"
) )
var installCmd = &cli.Command{ func InstallCmd() *cli.Command {
Name: "install",
Usage: "Install a new package", return &cli.Command{
Aliases: []string{"in"}, Name: "install",
Flags: []cli.Flag{ Usage: gotext.Get("Install a new package"),
&cli.BoolFlag{ Aliases: []string{"in"},
Name: "clean", Flags: []cli.Flag{
Aliases: []string{"c"}, &cli.BoolFlag{
Usage: "Build package from scratch even if there's an already built package available", Name: "clean",
Aliases: []string{"c"},
Usage: "Build package from scratch even if there's an already built package available",
},
}, },
}, Action: func(c *cli.Context) error {
Action: func(c *cli.Context) error { ctx := c.Context
ctx := c.Context
args := c.Args() args := c.Args()
if args.Len() < 1 { if args.Len() < 1 {
slog.Error(gotext.Get("Command install expected at least 1 argument, got %d", args.Len())) slog.Error(gotext.Get("Command install expected at least 1 argument, got %d", args.Len()))
os.Exit(1)
}
mgr := manager.Detect()
if mgr == nil {
slog.Error(gotext.Get("Unable to detect a supported package manager on the system"))
os.Exit(1)
}
err := repos.Pull(ctx, config.Config(ctx).Repos)
if err != nil {
slog.Error(gotext.Get("Error pulling repositories"), "err", err)
os.Exit(1)
}
found, notFound, err := repos.FindPkgs(ctx, args.Slice())
if err != nil {
slog.Error(gotext.Get("Error finding packages"), "err", err)
os.Exit(1)
}
pkgs := cliutils.FlattenPkgs(ctx, found, "install", c.Bool("interactive"))
build.InstallPkgs(ctx, pkgs, notFound, types.BuildOpts{
Manager: mgr,
Clean: c.Bool("clean"),
Interactive: c.Bool("interactive"),
})
return nil
},
BashComplete: func(c *cli.Context) {
result, err := db.GetPkgs(c.Context, "true")
if err != nil {
slog.Error(gotext.Get("Error getting packages"), "err", err)
os.Exit(1)
}
defer result.Close()
for result.Next() {
var pkg db.Package
err = result.StructScan(&pkg)
if err != nil {
slog.Error(gotext.Get("Error iterating over packages"), "err", err)
os.Exit(1) os.Exit(1)
} }
fmt.Println(pkg.Name) mgr := manager.Detect()
} if mgr == nil {
}, slog.Error(gotext.Get("Unable to detect a supported package manager on the system"))
os.Exit(1)
}
err := repos.Pull(ctx, config.Config(ctx).Repos)
if err != nil {
slog.Error(gotext.Get("Error pulling repositories"), "err", err)
os.Exit(1)
}
found, notFound, err := repos.FindPkgs(ctx, args.Slice())
if err != nil {
slog.Error(gotext.Get("Error finding packages"), "err", err)
os.Exit(1)
}
pkgs := cliutils.FlattenPkgs(ctx, found, "install", c.Bool("interactive"))
build.InstallPkgs(ctx, pkgs, notFound, types.BuildOpts{
Manager: mgr,
Clean: c.Bool("clean"),
Interactive: c.Bool("interactive"),
})
return nil
},
BashComplete: func(c *cli.Context) {
result, err := db.GetPkgs(c.Context, "true")
if err != nil {
slog.Error(gotext.Get("Error getting packages"), "err", err)
os.Exit(1)
}
defer result.Close()
for result.Next() {
var pkg db.Package
err = result.StructScan(&pkg)
if err != nil {
slog.Error(gotext.Get("Error iterating over packages"), "err", err)
os.Exit(1)
}
fmt.Println(pkg.Name)
}
},
}
} }
var removeCmd = &cli.Command{ func RemoveCmd() *cli.Command {
Name: "remove", return &cli.Command{
Usage: "Remove an installed package", Name: "remove",
Aliases: []string{"rm"}, Usage: gotext.Get("Remove an installed package"),
Action: func(c *cli.Context) error { Aliases: []string{"rm"},
args := c.Args() Action: func(c *cli.Context) error {
if args.Len() < 1 { args := c.Args()
slog.Error(gotext.Get("Command remove expected at least 1 argument, got %d", args.Len())) if args.Len() < 1 {
os.Exit(1) slog.Error(gotext.Get("Command remove expected at least 1 argument, got %d", args.Len()))
} os.Exit(1)
}
mgr := manager.Detect() mgr := manager.Detect()
if mgr == nil { if mgr == nil {
slog.Error(gotext.Get("Unable to detect a supported package manager on the system")) slog.Error(gotext.Get("Unable to detect a supported package manager on the system"))
os.Exit(1) os.Exit(1)
} }
err := mgr.Remove(nil, c.Args().Slice()...) err := mgr.Remove(nil, c.Args().Slice()...)
if err != nil { if err != nil {
slog.Error(gotext.Get("Error removing packages"), "err", err) slog.Error(gotext.Get("Error removing packages"), "err", err)
os.Exit(1) os.Exit(1)
} }
return nil return nil
}, },
}
} }

@ -9,51 +9,92 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: build.go:69 #: build.go:41
msgid "Build a local package"
msgstr ""
#: build.go:47
msgid "Path to the build script"
msgstr ""
#: build.go:52
msgid "Name of the package to build and its repo (example: default/go-bin)"
msgstr ""
#: build.go:57
msgid ""
"Build package from scratch even if there's an already built package available"
msgstr ""
#: build.go:70
msgid "Error pulling repositories" msgid "Error pulling repositories"
msgstr "" msgstr ""
#: build.go:75 #: build.go:76
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:86 #: build.go:87
msgid "Error building package" msgid "Error building package"
msgstr "" msgstr ""
#: build.go:92 #: build.go:93
msgid "Error getting working directory" msgid "Error getting working directory"
msgstr "" msgstr ""
#: build.go:100 #: build.go:101
msgid "Error moving the package" msgid "Error moving the package"
msgstr "" msgstr ""
#: fix.go:43 #: fix.go:37
msgid "Attempt to fix problems with ALR"
msgstr ""
#: fix.go:44
msgid "Removing cache directory" msgid "Removing cache directory"
msgstr "" msgstr ""
#: fix.go:47 #: fix.go:48
msgid "Unable to remove cache directory" msgid "Unable to remove cache directory"
msgstr "" msgstr ""
#: fix.go:51 #: fix.go:52
msgid "Rebuilding cache" msgid "Rebuilding cache"
msgstr "" msgstr ""
#: fix.go:55 #: fix.go:56
msgid "Unable to create new cache directory" msgid "Unable to create new cache directory"
msgstr "" msgstr ""
#: fix.go:61 #: fix.go:62
msgid "Error pulling repos" msgid "Error pulling repos"
msgstr "" msgstr ""
#: fix.go:65 #: fix.go:66
msgid "Done" msgid "Done"
msgstr "" msgstr ""
#: gen.go:34
msgid "Generate a ALR script from a template"
msgstr ""
#: gen.go:39
msgid "Generate a ALR script for a pip module"
msgstr ""
#: helper.go:41
msgid "List all the available helper commands"
msgstr ""
#: helper.go:53
msgid "Run a ALR helper command"
msgstr ""
#: helper.go:60 #: helper.go:60
msgid "The directory that the install commands will install to"
msgstr ""
#: helper.go:73
msgid "No such helper command" msgid "No such helper command"
msgstr "" msgstr ""
@ -85,23 +126,27 @@ msgstr ""
msgid "Error encoding script variables" msgid "Error encoding script variables"
msgstr "" msgstr ""
#: install.go:55 #: install.go:57
msgid "Command install expected at least 1 argument, got %d" msgid "Command install expected at least 1 argument, got %d"
msgstr "" msgstr ""
#: install.go:88 #: install.go:90
msgid "Error getting packages" msgid "Error getting packages"
msgstr "" msgstr ""
#: install.go:97 #: install.go:99
msgid "Error iterating over packages" msgid "Error iterating over packages"
msgstr "" msgstr ""
#: install.go:113 #: install.go:112
msgid "Remove an installed package"
msgstr ""
#: install.go:117
msgid "Command remove expected at least 1 argument, got %d" msgid "Command remove expected at least 1 argument, got %d"
msgstr "" msgstr ""
#: install.go:125 #: install.go:129
msgid "Error removing packages" msgid "Error removing packages"
msgstr "" msgstr ""
@ -202,21 +247,37 @@ msgstr ""
msgid "ERROR" msgid "ERROR"
msgstr "" msgstr ""
#: list.go:53 #: list.go:40
msgid "List ALR repo packages"
msgstr ""
#: list.go:54
msgid "Error initialization database" msgid "Error initialization database"
msgstr "" msgstr ""
#: list.go:87 #: list.go:88
msgid "Error listing installed packages" msgid "Error listing installed packages"
msgstr "" msgstr ""
#: main.go:88 #: main.go:45
msgid "Print the current ALR version and exit"
msgstr ""
#: main.go:61
msgid "Arguments to be passed on to the package manager"
msgstr ""
#: main.go:67
msgid "Enable interactive questions and prompts"
msgstr ""
#: main.go:90
msgid "" msgid ""
"Running ALR as root is forbidden as it may cause catastrophic damage to your " "Running ALR as root is forbidden as it may cause catastrophic damage to your "
"system" "system"
msgstr "" msgstr ""
#: main.go:122 #: main.go:124
msgid "Error while running app" msgid "Error while running app"
msgstr "" msgstr ""
@ -328,26 +389,54 @@ msgid ""
"updating ALR if something doesn't work." "updating ALR if something doesn't work."
msgstr "" msgstr ""
#: repo.go:78 repo.go:133 #: repo.go:41
msgid "Add a new repository"
msgstr ""
#: repo.go:48
msgid "Name of the new repo"
msgstr ""
#: repo.go:54
msgid "URL of the new repo"
msgstr ""
#: repo.go:79 repo.go:136
msgid "Error opening config file" msgid "Error opening config file"
msgstr "" msgstr ""
#: repo.go:84 repo.go:139 #: repo.go:85 repo.go:142
msgid "Error encoding config" msgid "Error encoding config"
msgstr "" msgstr ""
#: repo.go:125 #: repo.go:103
msgid "Remove an existing repository"
msgstr ""
#: repo.go:110
msgid "Name of the repo to be deleted"
msgstr ""
#: repo.go:128
msgid "Repo does not exist" msgid "Repo does not exist"
msgstr "" msgstr ""
#: repo.go:145 #: repo.go:148
msgid "Error removing repo directory" msgid "Error removing repo directory"
msgstr "" msgstr ""
#: repo.go:151 #: repo.go:154
msgid "Error removing packages from database" msgid "Error removing packages from database"
msgstr "" msgstr ""
#: upgrade.go:78 #: repo.go:166
msgid "Pull all repositories that have changed"
msgstr ""
#: upgrade.go:47
msgid "Upgrade all installed packages"
msgstr ""
#: upgrade.go:79
msgid "Error checking for updates" msgid "Error checking for updates"
msgstr "" msgstr ""

@ -11,55 +11,98 @@ msgstr ""
"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:69 #: build.go:41
#, fuzzy
msgid "Build a local package"
msgstr "Сборка пакета"
#: build.go:47
#, fuzzy
msgid "Path to the build script"
msgstr "Не удалось предложить просмотреть скрипт"
#: build.go:52
msgid "Name of the package to build and its repo (example: default/go-bin)"
msgstr ""
#: build.go:57
msgid ""
"Build package from scratch even if there's an already built package available"
msgstr ""
#: build.go:70
msgid "Error pulling repositories" msgid "Error pulling repositories"
msgstr "" msgstr ""
#: build.go:75 #: build.go:76
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:86 #: build.go:87
msgid "Error building package" msgid "Error building package"
msgstr "Ошибка при сборке пакета" msgstr "Ошибка при сборке пакета"
#: build.go:92 #: build.go:93
msgid "Error getting working directory" msgid "Error getting working directory"
msgstr "" msgstr ""
#: build.go:100 #: build.go:101
msgid "Error moving the package" msgid "Error moving the package"
msgstr "" msgstr ""
#: fix.go:43 #: fix.go:37
msgid "Attempt to fix problems with ALR"
msgstr ""
#: fix.go:44
msgid "Removing cache directory" msgid "Removing cache directory"
msgstr "" msgstr ""
#: fix.go:47 #: fix.go:48
msgid "Unable to remove cache directory" msgid "Unable to remove cache directory"
msgstr "" msgstr ""
#: fix.go:51 #: fix.go:52
msgid "Rebuilding cache" msgid "Rebuilding cache"
msgstr "" msgstr ""
#: fix.go:55 #: fix.go:56
msgid "Unable to create new cache directory" msgid "Unable to create new cache directory"
msgstr "" msgstr ""
#: fix.go:61 #: fix.go:62
msgid "Error pulling repos" msgid "Error pulling repos"
msgstr "" msgstr ""
#: fix.go:65 #: fix.go:66
msgid "Done" msgid "Done"
msgstr "" msgstr ""
#: gen.go:34
msgid "Generate a ALR script from a template"
msgstr ""
#: gen.go:39
msgid "Generate a ALR script for a pip module"
msgstr ""
#: helper.go:41
msgid "List all the available helper commands"
msgstr ""
#: helper.go:53
msgid "Run a ALR helper command"
msgstr ""
#: helper.go:60 #: helper.go:60
msgid "The directory that the install commands will install to"
msgstr ""
#: helper.go:73
msgid "No such helper command" msgid "No such helper command"
msgstr "" msgstr ""
@ -91,23 +134,27 @@ msgstr ""
msgid "Error encoding script variables" msgid "Error encoding script variables"
msgstr "" msgstr ""
#: install.go:55 #: install.go:57
msgid "Command install expected at least 1 argument, got %d" msgid "Command install expected at least 1 argument, got %d"
msgstr "" msgstr ""
#: install.go:88 #: install.go:90
msgid "Error getting packages" msgid "Error getting packages"
msgstr "" msgstr ""
#: install.go:97 #: install.go:99
msgid "Error iterating over packages" msgid "Error iterating over packages"
msgstr "" msgstr ""
#: install.go:113 #: install.go:112
msgid "Remove an installed package"
msgstr ""
#: install.go:117
msgid "Command remove expected at least 1 argument, got %d" msgid "Command remove expected at least 1 argument, got %d"
msgstr "" msgstr ""
#: install.go:125 #: install.go:129
msgid "Error removing packages" msgid "Error removing packages"
msgstr "" msgstr ""
@ -208,21 +255,37 @@ msgstr "Скачивание источника"
msgid "ERROR" msgid "ERROR"
msgstr "ОШИБКА" msgstr "ОШИБКА"
#: list.go:53 #: list.go:40
msgid "List ALR repo packages"
msgstr ""
#: list.go:54
msgid "Error initialization database" msgid "Error initialization database"
msgstr "" msgstr ""
#: list.go:87 #: list.go:88
msgid "Error listing installed packages" msgid "Error listing installed packages"
msgstr "" msgstr ""
#: main.go:88 #: main.go:45
msgid "Print the current ALR version and exit"
msgstr ""
#: main.go:61
msgid "Arguments to be passed on to the package manager"
msgstr ""
#: main.go:67
msgid "Enable interactive questions and prompts"
msgstr ""
#: main.go:90
msgid "" msgid ""
"Running ALR as root is forbidden as it may cause catastrophic damage to your " "Running ALR as root is forbidden as it may cause catastrophic damage to your "
"system" "system"
msgstr "" msgstr ""
#: main.go:122 #: main.go:124
msgid "Error while running app" msgid "Error while running app"
msgstr "" msgstr ""
@ -334,26 +397,55 @@ msgid ""
"updating ALR if something doesn't work." "updating ALR if something doesn't work."
msgstr "" msgstr ""
#: repo.go:78 repo.go:133 #: repo.go:41
#, fuzzy
msgid "Add a new repository"
msgstr "Скачивание репозитория"
#: repo.go:48
msgid "Name of the new repo"
msgstr ""
#: repo.go:54
msgid "URL of the new repo"
msgstr ""
#: repo.go:79 repo.go:136
msgid "Error opening config file" msgid "Error opening config file"
msgstr "" msgstr ""
#: repo.go:84 repo.go:139 #: repo.go:85 repo.go:142
msgid "Error encoding config" msgid "Error encoding config"
msgstr "" msgstr ""
#: repo.go:125 #: repo.go:103
msgid "Remove an existing repository"
msgstr ""
#: repo.go:110
msgid "Name of the repo to be deleted"
msgstr ""
#: repo.go:128
msgid "Repo does not exist" msgid "Repo does not exist"
msgstr "" msgstr ""
#: repo.go:145 #: repo.go:148
msgid "Error removing repo directory" msgid "Error removing repo directory"
msgstr "" msgstr ""
#: repo.go:151 #: repo.go:154
msgid "Error removing packages from database" msgid "Error removing packages from database"
msgstr "" msgstr ""
#: upgrade.go:78 #: repo.go:166
msgid "Pull all repositories that have changed"
msgstr ""
#: upgrade.go:47
msgid "Upgrade all installed packages"
msgstr ""
#: upgrade.go:79
msgid "Error checking for updates" msgid "Error checking for updates"
msgstr "" msgstr ""

146
list.go

@ -34,90 +34,92 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/repos" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/repos"
) )
var listCmd = &cli.Command{ func ListCmd() *cli.Command {
Name: "list", return &cli.Command{
Usage: "List ALR repo packages", Name: "list",
Aliases: []string{"ls"}, Usage: gotext.Get("List ALR repo packages"),
Flags: []cli.Flag{ Aliases: []string{"ls"},
&cli.BoolFlag{ Flags: []cli.Flag{
Name: "installed", &cli.BoolFlag{
Aliases: []string{"I"}, Name: "installed",
Aliases: []string{"I"},
},
}, },
}, Action: func(c *cli.Context) error {
Action: func(c *cli.Context) error { ctx := c.Context
ctx := c.Context cfg := config.New()
cfg := config.New() db := database.New(cfg)
db := database.New(cfg) err := db.Init(ctx)
err := db.Init(ctx) if err != nil {
if err != nil { slog.Error(gotext.Get("Error initialization database"), "err", err)
slog.Error(gotext.Get("Error initialization database"), "err", err) os.Exit(1)
os.Exit(1) }
} rs := repos.New(cfg, db)
rs := repos.New(cfg, db) err = rs.Pull(ctx, cfg.Repos(ctx))
err = rs.Pull(ctx, cfg.Repos(ctx)) if err != nil {
if err != nil { slog.Error(gotext.Get("Error pulling repositories"), "err", err)
slog.Error(gotext.Get("Error pulling repositories"), "err", err)
os.Exit(1)
}
where := "true"
args := []any(nil)
if c.NArg() > 0 {
where = "name LIKE ? OR json_array_contains(provides, ?)"
args = []any{c.Args().First(), c.Args().First()}
}
result, err := db.GetPkgs(ctx, where, args...)
if err != nil {
slog.Error(gotext.Get("Error getting packages"), "err", err)
os.Exit(1)
}
defer result.Close()
var installed map[string]string
if c.Bool("installed") {
mgr := manager.Detect()
if mgr == nil {
slog.Error(gotext.Get("Unable to detect a supported package manager on the system"))
os.Exit(1) os.Exit(1)
} }
installed, err = mgr.ListInstalled(&manager.Opts{AsRoot: false}) where := "true"
args := []any(nil)
if c.NArg() > 0 {
where = "name LIKE ? OR json_array_contains(provides, ?)"
args = []any{c.Args().First(), c.Args().First()}
}
result, err := db.GetPkgs(ctx, where, args...)
if err != nil { if err != nil {
slog.Error(gotext.Get("Error listing installed packages"), "err", err) slog.Error(gotext.Get("Error getting packages"), "err", err)
os.Exit(1) os.Exit(1)
} }
} defer result.Close()
for result.Next() { var installed map[string]string
var pkg database.Package
err := result.StructScan(&pkg)
if err != nil {
return err
}
if slices.Contains(cfg.IgnorePkgUpdates(ctx), pkg.Name) {
continue
}
version := pkg.Version
if c.Bool("installed") { if c.Bool("installed") {
instVersion, ok := installed[pkg.Name] mgr := manager.Detect()
if !ok { if mgr == nil {
continue slog.Error(gotext.Get("Unable to detect a supported package manager on the system"))
} else { os.Exit(1)
version = instVersion }
installed, err = mgr.ListInstalled(&manager.Opts{AsRoot: false})
if err != nil {
slog.Error(gotext.Get("Error listing installed packages"), "err", err)
os.Exit(1)
} }
} }
fmt.Printf("%s/%s %s\n", pkg.Repository, pkg.Name, version) for result.Next() {
} var pkg database.Package
err := result.StructScan(&pkg)
if err != nil {
return err
}
if err != nil { if slices.Contains(cfg.IgnorePkgUpdates(ctx), pkg.Name) {
slog.Error(gotext.Get("Error iterating over packages"), "err", err) continue
os.Exit(1) }
}
return nil version := pkg.Version
}, if c.Bool("installed") {
instVersion, ok := installed[pkg.Name]
if !ok {
continue
} else {
version = instVersion
}
}
fmt.Printf("%s/%s %s\n", pkg.Repository, pkg.Name, version)
}
if err != nil {
slog.Error(gotext.Get("Error iterating over packages"), "err", err)
os.Exit(1)
}
return nil
},
}
} }

46
main.go

@ -39,13 +39,15 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/logger" "gitea.plemya-x.ru/Plemya-x/ALR/internal/logger"
) )
var versionCmd = &cli.Command{ func VersionCmd() *cli.Command {
Name: "version", return &cli.Command{
Usage: "Print the current ALR version and exit", Name: "version",
Action: func(ctx *cli.Context) error { Usage: gotext.Get("Print the current ALR version and exit"),
println(config.Version) Action: func(ctx *cli.Context) error {
return nil println(config.Version)
}, return nil
},
}
} }
func GetApp() *cli.App { func GetApp() *cli.App {
@ -56,29 +58,29 @@ func GetApp() *cli.App {
&cli.StringFlag{ &cli.StringFlag{
Name: "pm-args", Name: "pm-args",
Aliases: []string{"P"}, Aliases: []string{"P"},
Usage: "Arguments to be passed on to the package manager", Usage: gotext.Get("Arguments to be passed on to the package manager"),
}, },
&cli.BoolFlag{ &cli.BoolFlag{
Name: "interactive", Name: "interactive",
Aliases: []string{"i"}, Aliases: []string{"i"},
Value: isatty.IsTerminal(os.Stdin.Fd()), Value: isatty.IsTerminal(os.Stdin.Fd()),
Usage: "Enable interactive questions and prompts", Usage: gotext.Get("Enable interactive questions and prompts"),
}, },
}, },
Commands: []*cli.Command{ Commands: []*cli.Command{
installCmd, InstallCmd(),
removeCmd, RemoveCmd(),
upgradeCmd, UpgradeCmd(),
GetInfoCmd(), InfoCmd(),
listCmd, ListCmd(),
buildCmd, BuildCmd(),
addrepoCmd, AddRepoCmd(),
removerepoCmd, RemoveRepoCmd(),
refreshCmd, RefreshCmd(),
fixCmd, FixCmd(),
genCmd, GenCmd(),
helperCmd, HelperCmd(),
versionCmd, VersionCmd(),
}, },
Before: func(c *cli.Context) error { Before: func(c *cli.Context) error {
ctx := c.Context ctx := c.Context

250
repo.go

@ -35,138 +35,144 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/repos" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/repos"
) )
var addrepoCmd = &cli.Command{ func AddRepoCmd() *cli.Command {
Name: "addrepo", return &cli.Command{
Usage: "Add a new repository", Name: "addrepo",
Aliases: []string{"ar"}, Usage: gotext.Get("Add a new repository"),
Flags: []cli.Flag{ Aliases: []string{"ar"},
&cli.StringFlag{ Flags: []cli.Flag{
Name: "name", &cli.StringFlag{
Aliases: []string{"n"}, Name: "name",
Required: true, Aliases: []string{"n"},
Usage: "Name of the new repo", Required: true,
Usage: gotext.Get("Name of the new repo"),
},
&cli.StringFlag{
Name: "url",
Aliases: []string{"u"},
Required: true,
Usage: gotext.Get("URL of the new repo"),
},
}, },
&cli.StringFlag{ Action: func(c *cli.Context) error {
Name: "url", ctx := c.Context
Aliases: []string{"u"},
Required: true,
Usage: "URL of the new repo",
},
},
Action: func(c *cli.Context) error {
ctx := c.Context
name := c.String("name") name := c.String("name")
repoURL := c.String("url") repoURL := c.String("url")
cfg := config.Config(ctx) cfg := config.Config(ctx)
for _, repo := range cfg.Repos { for _, repo := range cfg.Repos {
if repo.URL == repoURL { if repo.URL == repoURL {
slog.Error("Repo already exists", "name", repo.Name) slog.Error("Repo already exists", "name", repo.Name)
os.Exit(1)
}
}
cfg.Repos = append(cfg.Repos, types.Repo{
Name: name,
URL: repoURL,
})
cfgFl, err := os.Create(config.GetPaths(ctx).ConfigPath)
if err != nil {
slog.Error(gotext.Get("Error opening config file"), "err", err)
os.Exit(1) os.Exit(1)
} }
}
cfg.Repos = append(cfg.Repos, types.Repo{ err = toml.NewEncoder(cfgFl).Encode(cfg)
Name: name, if err != nil {
URL: repoURL, slog.Error(gotext.Get("Error encoding config"), "err", err)
}) os.Exit(1)
cfgFl, err := os.Create(config.GetPaths(ctx).ConfigPath)
if err != nil {
slog.Error(gotext.Get("Error opening config file"), "err", err)
os.Exit(1)
}
err = toml.NewEncoder(cfgFl).Encode(cfg)
if err != nil {
slog.Error(gotext.Get("Error encoding config"), "err", err)
os.Exit(1)
}
err = repos.Pull(ctx, cfg.Repos)
if err != nil {
slog.Error(gotext.Get("Error pulling repos"), "err", err)
os.Exit(1)
}
return nil
},
}
var removerepoCmd = &cli.Command{
Name: "removerepo",
Usage: "Remove an existing repository",
Aliases: []string{"rr"},
Flags: []cli.Flag{
&cli.StringFlag{
Name: "name",
Aliases: []string{"n"},
Required: true,
Usage: "Name of the repo to be deleted",
},
},
Action: func(c *cli.Context) error {
ctx := c.Context
name := c.String("name")
cfg := config.Config(ctx)
found := false
index := 0
for i, repo := range cfg.Repos {
if repo.Name == name {
index = i
found = true
} }
}
if !found {
slog.Error(gotext.Get("Repo does not exist"), "name", name)
os.Exit(1)
}
cfg.Repos = slices.Delete(cfg.Repos, index, index+1) err = repos.Pull(ctx, cfg.Repos)
if err != nil {
slog.Error(gotext.Get("Error pulling repos"), "err", err)
os.Exit(1)
}
cfgFl, err := os.Create(config.GetPaths(ctx).ConfigPath) return nil
if err != nil { },
slog.Error(gotext.Get("Error opening config file"), "err", err) }
os.Exit(1)
}
err = toml.NewEncoder(cfgFl).Encode(&cfg)
if err != nil {
slog.Error(gotext.Get("Error encoding config"), "err", err)
os.Exit(1)
}
err = os.RemoveAll(filepath.Join(config.GetPaths(ctx).RepoDir, name))
if err != nil {
slog.Error(gotext.Get("Error removing repo directory"), "err", err)
os.Exit(1)
}
err = db.DeletePkgs(ctx, "repository = ?", name)
if err != nil {
slog.Error(gotext.Get("Error removing packages from database"), "err", err)
os.Exit(1)
}
return nil
},
} }
var refreshCmd = &cli.Command{ func RemoveRepoCmd() *cli.Command {
Name: "refresh", return &cli.Command{
Usage: "Pull all repositories that have changed", Name: "removerepo",
Aliases: []string{"ref"}, Usage: gotext.Get("Remove an existing repository"),
Action: func(c *cli.Context) error { Aliases: []string{"rr"},
ctx := c.Context Flags: []cli.Flag{
err := repos.Pull(ctx, config.Config(ctx).Repos) &cli.StringFlag{
if err != nil { Name: "name",
slog.Error(gotext.Get("Error pulling repos"), "err", err) Aliases: []string{"n"},
os.Exit(1) Required: true,
} Usage: gotext.Get("Name of the repo to be deleted"),
return nil },
}, },
Action: func(c *cli.Context) error {
ctx := c.Context
name := c.String("name")
cfg := config.Config(ctx)
found := false
index := 0
for i, repo := range cfg.Repos {
if repo.Name == name {
index = i
found = true
}
}
if !found {
slog.Error(gotext.Get("Repo does not exist"), "name", name)
os.Exit(1)
}
cfg.Repos = slices.Delete(cfg.Repos, index, index+1)
cfgFl, err := os.Create(config.GetPaths(ctx).ConfigPath)
if err != nil {
slog.Error(gotext.Get("Error opening config file"), "err", err)
os.Exit(1)
}
err = toml.NewEncoder(cfgFl).Encode(&cfg)
if err != nil {
slog.Error(gotext.Get("Error encoding config"), "err", err)
os.Exit(1)
}
err = os.RemoveAll(filepath.Join(config.GetPaths(ctx).RepoDir, name))
if err != nil {
slog.Error(gotext.Get("Error removing repo directory"), "err", err)
os.Exit(1)
}
err = db.DeletePkgs(ctx, "repository = ?", name)
if err != nil {
slog.Error(gotext.Get("Error removing packages from database"), "err", err)
os.Exit(1)
}
return nil
},
}
}
func RefreshCmd() *cli.Command {
return &cli.Command{
Name: "refresh",
Usage: gotext.Get("Pull all repositories that have changed"),
Aliases: []string{"ref"},
Action: func(c *cli.Context) error {
ctx := c.Context
err := repos.Pull(ctx, config.Config(ctx).Repos)
if err != nil {
slog.Error(gotext.Get("Error pulling repos"), "err", err)
os.Exit(1)
}
return nil
},
}
} }

@ -41,56 +41,58 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/repos" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/repos"
) )
var upgradeCmd = &cli.Command{ func UpgradeCmd() *cli.Command {
Name: "upgrade", return &cli.Command{
Usage: "Upgrade all installed packages", Name: "upgrade",
Aliases: []string{"up"}, Usage: gotext.Get("Upgrade all installed packages"),
Flags: []cli.Flag{ Aliases: []string{"up"},
&cli.BoolFlag{ Flags: []cli.Flag{
Name: "clean", &cli.BoolFlag{
Aliases: []string{"c"}, Name: "clean",
Usage: "Build package from scratch even if there's an already built package available", 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 {
Action: func(c *cli.Context) error { ctx := c.Context
ctx := c.Context
info, err := distro.ParseOSRelease(ctx) info, err := distro.ParseOSRelease(ctx)
if err != nil { if err != nil {
slog.Error(gotext.Get("Error parsing os-release file"), "err", err) slog.Error(gotext.Get("Error parsing os-release file"), "err", err)
os.Exit(1) os.Exit(1)
} }
mgr := manager.Detect() mgr := manager.Detect()
if mgr == nil { if mgr == nil {
slog.Error(gotext.Get("Unable to detect a supported package manager on the system")) slog.Error(gotext.Get("Unable to detect a supported package manager on the system"))
os.Exit(1) os.Exit(1)
} }
err = repos.Pull(ctx, config.Config(ctx).Repos) err = repos.Pull(ctx, config.Config(ctx).Repos)
if err != nil { if err != nil {
slog.Error(gotext.Get("Error pulling repos"), "err", err) slog.Error(gotext.Get("Error pulling repos"), "err", err)
os.Exit(1) os.Exit(1)
} }
updates, err := checkForUpdates(ctx, mgr, info) updates, err := checkForUpdates(ctx, mgr, 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)
} }
if len(updates) > 0 { if len(updates) > 0 {
build.InstallPkgs(ctx, updates, nil, types.BuildOpts{ build.InstallPkgs(ctx, updates, nil, types.BuildOpts{
Manager: mgr, Manager: mgr,
Clean: c.Bool("clean"), Clean: c.Bool("clean"),
Interactive: c.Bool("interactive"), Interactive: c.Bool("interactive"),
}) })
} else { } else {
log.Info("There is nothing to do.").Send() log.Info("There is nothing to do.").Send()
} }
return nil return nil
}, },
}
} }
func checkForUpdates(ctx context.Context, mgr manager.Manager, info *distro.OSRelease) ([]db.Package, error) { func checkForUpdates(ctx context.Context, mgr manager.Manager, info *distro.OSRelease) ([]db.Package, error) {