forked from Plemya-x/ALR
feat: support mirrors
This commit is contained in:
356
repo.go
356
repo.go
@ -20,8 +20,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/leonelquinteros/gotext"
|
||||
"github.com/urfave/cli/v2"
|
||||
@ -41,6 +43,8 @@ func RepoCmd() *cli.Command {
|
||||
RemoveRepoCmd(),
|
||||
AddRepoCmd(),
|
||||
SetRepoRefCmd(),
|
||||
RepoMirrorCmd(),
|
||||
SetUrlCmd(),
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -51,6 +55,21 @@ func RemoveRepoCmd() *cli.Command {
|
||||
Usage: gotext.Get("Remove an existing repository"),
|
||||
Aliases: []string{"rm"},
|
||||
ArgsUsage: gotext.Get("<name>"),
|
||||
BashComplete: func(c *cli.Context) {
|
||||
if c.NArg() == 0 {
|
||||
// Get repo names from config
|
||||
ctx := c.Context
|
||||
deps, err := appbuilder.New(ctx).WithConfig().Build()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer deps.Defer()
|
||||
|
||||
for _, repo := range deps.Cfg.Repos() {
|
||||
fmt.Println(repo.Name)
|
||||
}
|
||||
}
|
||||
},
|
||||
Action: utils.RootNeededAction(func(c *cli.Context) error {
|
||||
if c.Args().Len() < 1 {
|
||||
return cliutils.FormatCliExit("missing args", nil)
|
||||
@ -186,6 +205,21 @@ func SetRepoRefCmd() *cli.Command {
|
||||
Name: "set-ref",
|
||||
Usage: gotext.Get("Set the reference of the repository"),
|
||||
ArgsUsage: gotext.Get("<name> <ref>"),
|
||||
BashComplete: func(c *cli.Context) {
|
||||
if c.NArg() == 0 {
|
||||
// Get repo names from config
|
||||
ctx := c.Context
|
||||
deps, err := appbuilder.New(ctx).WithConfig().Build()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer deps.Defer()
|
||||
|
||||
for _, repo := range deps.Cfg.Repos() {
|
||||
fmt.Println(repo.Name)
|
||||
}
|
||||
}
|
||||
},
|
||||
Action: utils.RootNeededAction(func(c *cli.Context) error {
|
||||
if c.Args().Len() < 2 {
|
||||
return cliutils.FormatCliExit("missing args", nil)
|
||||
@ -229,6 +263,328 @@ func SetRepoRefCmd() *cli.Command {
|
||||
}
|
||||
}
|
||||
|
||||
func SetUrlCmd() *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "set-url",
|
||||
Usage: gotext.Get("Set the main url of the repository"),
|
||||
ArgsUsage: gotext.Get("<name> <url>"),
|
||||
BashComplete: func(c *cli.Context) {
|
||||
if c.NArg() == 0 {
|
||||
// Get repo names from config
|
||||
ctx := c.Context
|
||||
deps, err := appbuilder.New(ctx).WithConfig().Build()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer deps.Defer()
|
||||
|
||||
for _, repo := range deps.Cfg.Repos() {
|
||||
fmt.Println(repo.Name)
|
||||
}
|
||||
}
|
||||
},
|
||||
Action: utils.RootNeededAction(func(c *cli.Context) error {
|
||||
if c.Args().Len() < 2 {
|
||||
return cliutils.FormatCliExit("missing args", nil)
|
||||
}
|
||||
|
||||
name := c.Args().Get(0)
|
||||
repoUrl := c.Args().Get(1)
|
||||
|
||||
deps, err := appbuilder.
|
||||
New(c.Context).
|
||||
WithConfig().
|
||||
WithDB().
|
||||
WithReposNoPull().
|
||||
Build()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer deps.Defer()
|
||||
|
||||
repos := deps.Cfg.Repos()
|
||||
newRepos := []types.Repo{}
|
||||
for _, repo := range repos {
|
||||
if repo.Name == name {
|
||||
repo.URL = repoUrl
|
||||
}
|
||||
newRepos = append(newRepos, repo)
|
||||
}
|
||||
deps.Cfg.SetRepos(newRepos)
|
||||
err = deps.Cfg.SaveUserConfig()
|
||||
if err != nil {
|
||||
return cliutils.FormatCliExit(gotext.Get("Error saving config"), err)
|
||||
}
|
||||
|
||||
err = deps.Repos.Pull(c.Context, newRepos)
|
||||
if err != nil {
|
||||
return cliutils.FormatCliExit(gotext.Get("Error pulling repositories"), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
func RepoMirrorCmd() *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "mirror",
|
||||
Usage: gotext.Get("Manage mirrors of repos"),
|
||||
Subcommands: []*cli.Command{
|
||||
AddMirror(),
|
||||
RemoveMirror(),
|
||||
ClearMirrors(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func AddMirror() *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "add",
|
||||
Usage: gotext.Get("Add a mirror URL to repository"),
|
||||
ArgsUsage: gotext.Get("<name> <url>"),
|
||||
BashComplete: func(c *cli.Context) {
|
||||
if c.NArg() == 0 {
|
||||
ctx := c.Context
|
||||
deps, err := appbuilder.New(ctx).WithConfig().Build()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer deps.Defer()
|
||||
|
||||
for _, repo := range deps.Cfg.Repos() {
|
||||
fmt.Println(repo.Name)
|
||||
}
|
||||
}
|
||||
},
|
||||
Action: utils.RootNeededAction(func(c *cli.Context) error {
|
||||
if c.Args().Len() < 2 {
|
||||
return cliutils.FormatCliExit("missing args", nil)
|
||||
}
|
||||
|
||||
name := c.Args().Get(0)
|
||||
url := c.Args().Get(1)
|
||||
|
||||
deps, err := appbuilder.
|
||||
New(c.Context).
|
||||
WithConfig().
|
||||
WithDB().
|
||||
WithReposNoPull().
|
||||
Build()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer deps.Defer()
|
||||
|
||||
repos := deps.Cfg.Repos()
|
||||
for i, repo := range repos {
|
||||
if repo.Name == name {
|
||||
repos[i].Mirrors = append(repos[i].Mirrors, url)
|
||||
break
|
||||
}
|
||||
}
|
||||
deps.Cfg.SetRepos(repos)
|
||||
err = deps.Cfg.SaveUserConfig()
|
||||
if err != nil {
|
||||
return cliutils.FormatCliExit(gotext.Get("Error saving config"), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
func RemoveMirror() *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "remove",
|
||||
Aliases: []string{"rm"},
|
||||
Usage: gotext.Get("Remove mirror from the repository"),
|
||||
ArgsUsage: gotext.Get("<name> <url>"),
|
||||
BashComplete: func(c *cli.Context) {
|
||||
ctx := c.Context
|
||||
deps, err := appbuilder.New(ctx).WithConfig().Build()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer deps.Defer()
|
||||
|
||||
if c.NArg() == 0 {
|
||||
for _, repo := range deps.Cfg.Repos() {
|
||||
fmt.Println(repo.Name)
|
||||
}
|
||||
}
|
||||
},
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "ignore-missing",
|
||||
Usage: gotext.Get("Ignore if mirror does not exist"),
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "partial",
|
||||
Aliases: []string{"p"},
|
||||
Usage: gotext.Get("Match partial URL (e.g., github.com instead of full URL)"),
|
||||
},
|
||||
},
|
||||
Action: utils.RootNeededAction(func(c *cli.Context) error {
|
||||
if c.Args().Len() < 2 {
|
||||
return cliutils.FormatCliExit("missing args", nil)
|
||||
}
|
||||
|
||||
name := c.Args().Get(0)
|
||||
urlToRemove := c.Args().Get(1)
|
||||
ignoreMissing := c.Bool("ignore-missing")
|
||||
partialMatch := c.Bool("partial")
|
||||
|
||||
deps, err := appbuilder.
|
||||
New(c.Context).
|
||||
WithConfig().
|
||||
WithDB().
|
||||
WithReposNoPull().
|
||||
Build()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer deps.Defer()
|
||||
|
||||
reposSlice := deps.Cfg.Repos()
|
||||
repoIndex := -1
|
||||
urlIndicesToRemove := []int{}
|
||||
|
||||
// Находим репозиторий
|
||||
for i, repo := range reposSlice {
|
||||
if repo.Name == name {
|
||||
repoIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if repoIndex == -1 {
|
||||
if ignoreMissing {
|
||||
return nil // Тихо завершаем, если репозиторий не найден
|
||||
}
|
||||
return cliutils.FormatCliExit(gotext.Get("Repo \"%s\" does not exist", name), nil)
|
||||
}
|
||||
|
||||
// Ищем зеркала для удаления
|
||||
repo := reposSlice[repoIndex]
|
||||
for j, mirror := range repo.Mirrors {
|
||||
var match bool
|
||||
if partialMatch {
|
||||
// Частичное совпадение - проверяем, содержит ли зеркало указанную строку
|
||||
match = strings.Contains(mirror, urlToRemove)
|
||||
} else {
|
||||
// Точное совпадение
|
||||
match = mirror == urlToRemove
|
||||
}
|
||||
|
||||
if match {
|
||||
urlIndicesToRemove = append(urlIndicesToRemove, j)
|
||||
}
|
||||
}
|
||||
|
||||
if len(urlIndicesToRemove) == 0 {
|
||||
if ignoreMissing {
|
||||
return nil
|
||||
}
|
||||
if partialMatch {
|
||||
return cliutils.FormatCliExit(gotext.Get("No mirrors containing \"%s\" found in repo \"%s\"", urlToRemove, name), nil)
|
||||
} else {
|
||||
return cliutils.FormatCliExit(gotext.Get("URL \"%s\" does not exist in repo \"%s\"", urlToRemove, name), nil)
|
||||
}
|
||||
}
|
||||
|
||||
for i := len(urlIndicesToRemove) - 1; i >= 0; i-- {
|
||||
urlIndex := urlIndicesToRemove[i]
|
||||
reposSlice[repoIndex].Mirrors = slices.Delete(reposSlice[repoIndex].Mirrors, urlIndex, urlIndex+1)
|
||||
}
|
||||
|
||||
deps.Cfg.SetRepos(reposSlice)
|
||||
err = deps.Cfg.SaveUserConfig()
|
||||
if err != nil {
|
||||
return cliutils.FormatCliExit(gotext.Get("Error saving config"), err)
|
||||
}
|
||||
|
||||
if len(urlIndicesToRemove) > 1 {
|
||||
fmt.Println(gotext.Get("Removed %d mirrors from repo \"%s\"\n", len(urlIndicesToRemove), name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
func ClearMirrors() *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "clear",
|
||||
Aliases: []string{"rm-all"},
|
||||
Usage: gotext.Get("Remove all mirrors from the repository"),
|
||||
ArgsUsage: gotext.Get("<name>"),
|
||||
BashComplete: func(c *cli.Context) {
|
||||
if c.NArg() == 0 {
|
||||
// Get repo names from config
|
||||
ctx := c.Context
|
||||
deps, err := appbuilder.New(ctx).WithConfig().Build()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer deps.Defer()
|
||||
|
||||
for _, repo := range deps.Cfg.Repos() {
|
||||
fmt.Println(repo.Name)
|
||||
}
|
||||
}
|
||||
},
|
||||
Action: utils.RootNeededAction(func(c *cli.Context) error {
|
||||
if c.Args().Len() < 1 {
|
||||
return cliutils.FormatCliExit("missing args", nil)
|
||||
}
|
||||
|
||||
name := c.Args().Get(0)
|
||||
|
||||
deps, err := appbuilder.
|
||||
New(c.Context).
|
||||
WithConfig().
|
||||
WithDB().
|
||||
WithReposNoPull().
|
||||
Build()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer deps.Defer()
|
||||
|
||||
reposSlice := deps.Cfg.Repos()
|
||||
repoIndex := -1
|
||||
urlIndicesToRemove := []int{}
|
||||
|
||||
// Находим репозиторий
|
||||
for i, repo := range reposSlice {
|
||||
if repo.Name == name {
|
||||
repoIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if repoIndex == -1 {
|
||||
return cliutils.FormatCliExit(gotext.Get("Repo \"%s\" does not exist", name), nil)
|
||||
}
|
||||
|
||||
reposSlice[repoIndex].Mirrors = []string{}
|
||||
|
||||
deps.Cfg.SetRepos(reposSlice)
|
||||
err = deps.Cfg.SaveUserConfig()
|
||||
if err != nil {
|
||||
return cliutils.FormatCliExit(gotext.Get("Error saving config"), err)
|
||||
}
|
||||
|
||||
if len(urlIndicesToRemove) > 1 {
|
||||
fmt.Println(gotext.Get("Removed %d mirrors from repo \"%s\"\n", len(urlIndicesToRemove), name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: remove
|
||||
//
|
||||
// Deprecated: use "alr repo add"
|
||||
|
Reference in New Issue
Block a user