3 Commits

Author SHA1 Message Date
c632ddb354 add the ability to specify repository ref (#80)
closes #75

Reviewed-on: #80
Co-authored-by: Maxim Slipenko <no-reply@maxim.slipenko.com>
Co-committed-by: Maxim Slipenko <no-reply@maxim.slipenko.com>
2025-05-08 18:04:51 +00:00
76234bf00d Merge pull request 'adds a rootCmd call if necessary' (#79) from Maks1mS/ALR:add-root-cmd into master
Reviewed-on: #79
2025-05-08 17:24:55 +00:00
f8c510ab9f adds a rootCmd call if necessary 2025-05-08 20:23:24 +03:00
12 changed files with 305 additions and 117 deletions

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">16.4%</text> <text x="86" y="15" fill="#010101" fill-opacity=".3">17.0%</text>
<text x="86" y="14">16.4%</text> <text x="86" y="14">17.0%</text>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 926 B

After

Width:  |  Height:  |  Size: 926 B

View File

@@ -0,0 +1,62 @@
// ALR - Any Linux Repository
// Copyright (C) 2025 The ALR Authors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//go:build e2e
package e2etests_test
import (
"testing"
"github.com/alecthomas/assert/v2"
"github.com/efficientgo/e2e"
)
func TestE2EIssue75InstallWithDeps(t *testing.T) {
dockerMultipleRun(
t,
"issue-75-ref-specify",
COMMON_SYSTEMS,
func(t *testing.T, r e2e.Runnable) {
err := r.Exec(e2e.NewCommand(
"sudo",
"alr",
"addrepo",
"--name",
"alr-repo",
"--url",
"https://gitea.plemya-x.ru/Maks1mS/repo-for-tests.git",
))
assert.NoError(t, err)
err = r.Exec(e2e.NewCommand(
"sudo", "alr", "ref",
))
assert.NoError(t, err)
// TODO: replace with alr command when it be added
err = r.Exec(e2e.NewCommand(
"sudo", "sh", "-c", "sed -i 's/ref = .*/ref = \"bd26236cd7\"/' /etc/alr/alr.toml",
))
assert.NoError(t, err)
err = r.Exec(e2e.NewCommand(
"sh", "-c", "test $(alr list | wc -l) -eq 2 || exit 1",
))
assert.NoError(t, err)
},
)
}

View File

@@ -46,11 +46,7 @@ func InstallCmd() *cli.Command {
Usage: gotext.Get("Build package from scratch even if there's an already built package available"), Usage: gotext.Get("Build package from scratch even if there's an already built package available"),
}, },
}, },
Action: func(c *cli.Context) error { Action: utils.RootNeededAction(func(c *cli.Context) error {
if err := utils.ExitIfNotRoot(); err != nil {
return err
}
args := c.Args() args := c.Args()
if args.Len() < 1 { if args.Len() < 1 {
return cliutils.FormatCliExit(gotext.Get("Command install expected at least 1 argument, got %d", args.Len()), nil) return cliutils.FormatCliExit(gotext.Get("Command install expected at least 1 argument, got %d", args.Len()), nil)
@@ -119,7 +115,7 @@ func InstallCmd() *cli.Command {
} }
return nil return nil
}, }),
BashComplete: cliutils.BashCompleteWithError(func(c *cli.Context) error { BashComplete: cliutils.BashCompleteWithError(func(c *cli.Context) error {
if err := utils.ExitIfCantDropCapsToAlrUser(); err != nil { if err := utils.ExitIfCantDropCapsToAlrUser(); err != nil {
return err return err
@@ -213,11 +209,7 @@ func RemoveCmd() *cli.Command {
return nil return nil
}), }),
Action: func(c *cli.Context) error { Action: utils.RootNeededAction(func(c *cli.Context) error {
if err := utils.ExitIfNotRoot(); err != nil {
return err
}
args := c.Args() args := c.Args()
if args.Len() < 1 { if args.Len() < 1 {
return cliutils.FormatCliExit(gotext.Get("Command remove expected at least 1 argument, got %d", args.Len()), nil) return cliutils.FormatCliExit(gotext.Get("Command remove expected at least 1 argument, got %d", args.Len()), nil)
@@ -239,6 +231,6 @@ func RemoveCmd() *cli.Command {
} }
return nil return nil
}, }),
} }
} }

View File

@@ -39,6 +39,7 @@ type ALRConfig struct {
var defaultConfig = &types.Config{ var defaultConfig = &types.Config{
RootCmd: "sudo", RootCmd: "sudo",
UseRootCmd: true,
PagerStyle: "native", PagerStyle: "native",
IgnorePkgUpdates: []string{}, IgnorePkgUpdates: []string{},
AutoPull: true, AutoPull: true,
@@ -142,6 +143,10 @@ func (c *ALRConfig) LogLevel() string {
return c.cfg.LogLevel return c.cfg.LogLevel
} }
func (c *ALRConfig) UseRootCmd() bool {
return c.cfg.UseRootCmd
}
func (c *ALRConfig) GetPaths() *Paths { func (c *ALRConfig) GetPaths() *Paths {
return c.paths return c.paths
} }

View File

@@ -154,27 +154,27 @@ msgstr ""
msgid "Install a new package" msgid "Install a new package"
msgstr "" msgstr ""
#: install.go:56 #: install.go:52
msgid "Command install expected at least 1 argument, got %d" msgid "Command install expected at least 1 argument, got %d"
msgstr "" msgstr ""
#: install.go:118 #: install.go:114
msgid "Error when installing the package" msgid "Error when installing the package"
msgstr "" msgstr ""
#: install.go:163 #: install.go:159
msgid "Remove an installed package" msgid "Remove an installed package"
msgstr "" msgstr ""
#: install.go:182 #: install.go:178
msgid "Error listing installed packages" msgid "Error listing installed packages"
msgstr "" msgstr ""
#: install.go:223 #: install.go:215
msgid "Command remove expected at least 1 argument, got %d" msgid "Command remove expected at least 1 argument, got %d"
msgstr "" msgstr ""
#: install.go:238 #: install.go:230
msgid "Error removing packages" msgid "Error removing packages"
msgstr "" msgstr ""
@@ -315,16 +315,16 @@ msgstr ""
msgid "ERROR" msgid "ERROR"
msgstr "" msgstr ""
#: internal/utils/cmd.go:95 #: internal/utils/cmd.go:97
msgid "Error on dropping capabilities" msgid "Error on dropping capabilities"
msgstr "" msgstr ""
#: internal/utils/cmd.go:123 #: internal/utils/cmd.go:164
msgid "You need to be root to perform this action" msgid "You need to be a %s member to perform this action"
msgstr "" msgstr ""
#: internal/utils/cmd.go:165 #: internal/utils/cmd.go:200
msgid "You need to be a %s member to perform this action" msgid "You need to be root to perform this action"
msgstr "" msgstr ""
#: list.go:41 #: list.go:41
@@ -413,19 +413,19 @@ msgstr ""
msgid "Executing %s()" msgid "Executing %s()"
msgstr "" msgstr ""
#: pkg/repos/pull.go:79 #: pkg/repos/pull.go:80
msgid "Pulling repository" msgid "Pulling repository"
msgstr "" msgstr ""
#: pkg/repos/pull.go:103 #: pkg/repos/pull.go:116
msgid "Repository up to date" msgid "Repository up to date"
msgstr "" msgstr ""
#: pkg/repos/pull.go:160 #: pkg/repos/pull.go:207
msgid "Git repository does not appear to be a valid ALR repo" msgid "Git repository does not appear to be a valid ALR repo"
msgstr "" msgstr ""
#: pkg/repos/pull.go:176 #: pkg/repos/pull.go:223
msgid "" msgid ""
"ALR repo's minimum ALR version is greater than the current version. Try " "ALR repo's minimum ALR version is greater than the current version. Try "
"updating ALR if something doesn't work." "updating ALR if something doesn't work."
@@ -443,35 +443,35 @@ msgstr ""
msgid "URL of the new repo" msgid "URL of the new repo"
msgstr "" msgstr ""
#: repo.go:79 #: repo.go:75
msgid "Repo \"%s\" already exists" msgid "Repo \"%s\" already exists"
msgstr "" msgstr ""
#: repo.go:90 repo.go:167 #: repo.go:86 repo.go:159
msgid "Error saving config" msgid "Error saving config"
msgstr "" msgstr ""
#: repo.go:116 #: repo.go:112
msgid "Remove an existing repository" msgid "Remove an existing repository"
msgstr "" msgstr ""
#: repo.go:123 #: repo.go:119
msgid "Name of the repo to be deleted" msgid "Name of the repo to be deleted"
msgstr "" msgstr ""
#: repo.go:156 #: repo.go:148
msgid "Repo \"%s\" does not exist" msgid "Repo \"%s\" does not exist"
msgstr "" msgstr ""
#: repo.go:163 #: repo.go:155
msgid "Error removing repo directory" msgid "Error removing repo directory"
msgstr "" msgstr ""
#: repo.go:186 #: repo.go:178
msgid "Error removing packages from database" msgid "Error removing packages from database"
msgstr "" msgstr ""
#: repo.go:197 #: repo.go:189
msgid "Pull all repositories that have changed" msgid "Pull all repositories that have changed"
msgstr "" msgstr ""
@@ -515,10 +515,10 @@ msgstr ""
msgid "Upgrade all installed packages" msgid "Upgrade all installed packages"
msgstr "" msgstr ""
#: upgrade.go:109 upgrade.go:126 #: upgrade.go:105 upgrade.go:122
msgid "Error checking for updates" msgid "Error checking for updates"
msgstr "" msgstr ""
#: upgrade.go:129 #: upgrade.go:125
msgid "There is nothing to do." msgid "There is nothing to do."
msgstr "" msgstr ""

View File

@@ -12,8 +12,8 @@ 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 48.0\n" "X-Generator: Gtranslator 48.0\n"
#: build.go:42 #: build.go:42
@@ -161,27 +161,27 @@ msgstr "Ошибка кодирования переменных скрита"
msgid "Install a new package" msgid "Install a new package"
msgstr "Установить новый пакет" msgstr "Установить новый пакет"
#: install.go:56 #: install.go:52
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:118 #: install.go:114
msgid "Error when installing the package" msgid "Error when installing the package"
msgstr "Ошибка при установке пакета" msgstr "Ошибка при установке пакета"
#: install.go:163 #: install.go:159
msgid "Remove an installed package" msgid "Remove an installed package"
msgstr "Удалить установленный пакет" msgstr "Удалить установленный пакет"
#: install.go:182 #: install.go:178
msgid "Error listing installed packages" msgid "Error listing installed packages"
msgstr "Ошибка при составлении списка установленных пакетов" msgstr "Ошибка при составлении списка установленных пакетов"
#: install.go:223 #: install.go:215
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:238 #: install.go:230
msgid "Error removing packages" msgid "Error removing packages"
msgstr "Ошибка при удалении пакетов" msgstr "Ошибка при удалении пакетов"
@@ -323,18 +323,18 @@ msgstr "%s %s загружается — %s/с\n"
msgid "ERROR" msgid "ERROR"
msgstr "ОШИБКА" msgstr "ОШИБКА"
#: internal/utils/cmd.go:95 #: internal/utils/cmd.go:97
msgid "Error on dropping capabilities" msgid "Error on dropping capabilities"
msgstr "Ошибка при понижении привилегий" msgstr "Ошибка при понижении привилегий"
#: internal/utils/cmd.go:123 #: internal/utils/cmd.go:164
msgid "You need to be root to perform this action"
msgstr "Вы должны быть root чтобы выполнить это"
#: internal/utils/cmd.go:165
msgid "You need to be a %s member to perform this action" msgid "You need to be a %s member to perform this action"
msgstr "Вы должны быть членом %s чтобы выполнить это" msgstr "Вы должны быть членом %s чтобы выполнить это"
#: internal/utils/cmd.go:200
msgid "You need to be root to perform this action"
msgstr "Вы должны быть root чтобы выполнить это"
#: list.go:41 #: list.go:41
msgid "List ALR repo packages" msgid "List ALR repo packages"
msgstr "Список пакетов репозитория ALR" msgstr "Список пакетов репозитория ALR"
@@ -425,19 +425,19 @@ msgstr "Выполнение build()"
msgid "Executing %s()" msgid "Executing %s()"
msgstr "Выполнение %s()" msgstr "Выполнение %s()"
#: pkg/repos/pull.go:79 #: pkg/repos/pull.go:80
msgid "Pulling repository" msgid "Pulling repository"
msgstr "Скачивание репозитория" msgstr "Скачивание репозитория"
#: pkg/repos/pull.go:103 #: pkg/repos/pull.go:116
msgid "Repository up to date" msgid "Repository up to date"
msgstr "Репозиторий уже обновлён" msgstr "Репозиторий уже обновлён"
#: pkg/repos/pull.go:160 #: pkg/repos/pull.go:207
msgid "Git repository does not appear to be a valid ALR repo" msgid "Git repository does not appear to be a valid ALR repo"
msgstr "Репозиторий Git не поддерживается репозиторием ALR" msgstr "Репозиторий Git не поддерживается репозиторием ALR"
#: pkg/repos/pull.go:176 #: pkg/repos/pull.go:223
msgid "" msgid ""
"ALR repo's minimum ALR version is greater than the current version. Try " "ALR repo's minimum ALR version is greater than the current version. Try "
"updating ALR if something doesn't work." "updating ALR if something doesn't work."
@@ -457,35 +457,35 @@ msgstr "Название нового репозитория"
msgid "URL of the new repo" msgid "URL of the new repo"
msgstr "URL-адрес нового репозитория" msgstr "URL-адрес нового репозитория"
#: repo.go:79 #: repo.go:75
msgid "Repo \"%s\" already exists" msgid "Repo \"%s\" already exists"
msgstr "Репозиторий \"%s\" уже существует" msgstr "Репозиторий \"%s\" уже существует"
#: repo.go:90 repo.go:167 #: repo.go:86 repo.go:159
msgid "Error saving config" msgid "Error saving config"
msgstr "Ошибка при сохранении конфигурации" msgstr "Ошибка при сохранении конфигурации"
#: repo.go:116 #: repo.go:112
msgid "Remove an existing repository" msgid "Remove an existing repository"
msgstr "Удалить существующий репозиторий" msgstr "Удалить существующий репозиторий"
#: repo.go:123 #: repo.go:119
msgid "Name of the repo to be deleted" msgid "Name of the repo to be deleted"
msgstr "Название репозитория удалён" msgstr "Название репозитория удалён"
#: repo.go:156 #: repo.go:148
msgid "Repo \"%s\" does not exist" msgid "Repo \"%s\" does not exist"
msgstr "Репозитория \"%s\" не существует" msgstr "Репозитория \"%s\" не существует"
#: repo.go:163 #: repo.go:155
msgid "Error removing repo directory" msgid "Error removing repo directory"
msgstr "Ошибка при удалении каталога репозитория" msgstr "Ошибка при удалении каталога репозитория"
#: repo.go:186 #: repo.go:178
msgid "Error removing packages from database" msgid "Error removing packages from database"
msgstr "Ошибка при удалении пакетов из базы данных" msgstr "Ошибка при удалении пакетов из базы данных"
#: repo.go:197 #: repo.go:189
msgid "Pull all repositories that have changed" msgid "Pull all repositories that have changed"
msgstr "Скачать все изменённые репозитории" msgstr "Скачать все изменённые репозитории"
@@ -529,11 +529,11 @@ msgstr "Ошибка при выполнении шаблона"
msgid "Upgrade all installed packages" msgid "Upgrade all installed packages"
msgstr "Обновить все установленные пакеты" msgstr "Обновить все установленные пакеты"
#: upgrade.go:109 upgrade.go:126 #: upgrade.go:105 upgrade.go:122
msgid "Error checking for updates" msgid "Error checking for updates"
msgstr "Ошибка при проверке обновлений" msgstr "Ошибка при проверке обновлений"
#: upgrade.go:129 #: upgrade.go:125
msgid "There is nothing to do." msgid "There is nothing to do."
msgstr "Здесь нечего делать." msgstr "Здесь нечего делать."

View File

@@ -22,6 +22,7 @@ package types
// Config represents the ALR configuration file // Config represents the ALR configuration file
type Config struct { type Config struct {
RootCmd string `toml:"rootCmd" env:"ALR_ROOT_CMD"` RootCmd string `toml:"rootCmd" env:"ALR_ROOT_CMD"`
UseRootCmd bool `toml:"useRootCmd"`
PagerStyle string `toml:"pagerStyle" env:"ALR_PAGER_STYLE"` PagerStyle string `toml:"pagerStyle" env:"ALR_PAGER_STYLE"`
IgnorePkgUpdates []string `toml:"ignorePkgUpdates"` IgnorePkgUpdates []string `toml:"ignorePkgUpdates"`
Repos []Repo `toml:"repo"` Repos []Repo `toml:"repo"`
@@ -33,4 +34,5 @@ type Config struct {
type Repo struct { type Repo struct {
Name string `toml:"name"` Name string `toml:"name"`
URL string `toml:"url"` URL string `toml:"url"`
Ref string `toml:"ref"`
} }

View File

@@ -19,6 +19,7 @@ package utils
import ( import (
"errors" "errors"
"os" "os"
"os/exec"
"os/user" "os/user"
"strconv" "strconv"
"syscall" "syscall"
@@ -27,6 +28,7 @@ import (
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils" "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/constants" "gitea.plemya-x.ru/Plemya-x/ALR/internal/constants"
) )
@@ -118,11 +120,8 @@ func ExitIfCantDropCapsToAlrUserNoPrivs() cli.ExitCoder {
return nil return nil
} }
func ExitIfNotRoot() error { func IsNotRoot() bool {
if os.Getuid() != 0 { return os.Getuid() != 0
return cli.Exit(gotext.Get("You need to be root to perform this action"), 1)
}
return nil
} }
func EnsureIsAlrUser() error { func EnsureIsAlrUser() error {
@@ -184,3 +183,33 @@ func EscalateToRoot() error {
} }
return nil return nil
} }
func RootNeededAction(f cli.ActionFunc) cli.ActionFunc {
return func(ctx *cli.Context) error {
deps, err := appbuilder.
New(ctx.Context).
WithConfig().
Build()
if err != nil {
return err
}
defer deps.Defer()
if IsNotRoot() {
if !deps.Cfg.UseRootCmd() {
return cli.Exit(gotext.Get("You need to be root to perform this action"), 1)
}
executable, err := os.Executable()
if err != nil {
return cliutils.FormatCliExit("failed to get executable path", err)
}
args := append([]string{executable}, os.Args[1:]...)
cmd := exec.Command(deps.Cfg.RootCmd(), args...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}
return f(ctx)
}
}

View File

@@ -33,6 +33,7 @@ import (
"github.com/go-git/go-billy/v5" "github.com/go-git/go-billy/v5"
"github.com/go-git/go-billy/v5/osfs" "github.com/go-git/go-billy/v5/osfs"
"github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5"
gitConfig "github.com/go-git/go-git/v5/config"
"github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing"
"github.com/leonelquinteros/gotext" "github.com/leonelquinteros/gotext"
"github.com/pelletier/go-toml/v2" "github.com/pelletier/go-toml/v2"
@@ -88,6 +89,14 @@ func (rs *Repos) Pull(ctx context.Context, repos []types.Repo) error {
return err return err
} }
err = r.FetchContext(ctx, &git.FetchOptions{
Progress: os.Stderr,
Force: true,
})
if err != nil && !errors.Is(err, git.NoErrAlreadyUpToDate) {
return err
}
w, err := r.Worktree() w, err := r.Worktree()
if err != nil { if err != nil {
return err return err
@@ -98,16 +107,24 @@ func (rs *Repos) Pull(ctx context.Context, repos []types.Repo) error {
return err return err
} }
err = w.PullContext(ctx, &git.PullOptions{Progress: os.Stderr}) revHash, err := resolveHash(r, repo.Ref)
if errors.Is(err, git.NoErrAlreadyUpToDate) { if err != nil {
return fmt.Errorf("error resolving hash: %w", err)
}
if old.Hash() == *revHash {
slog.Info(gotext.Get("Repository up to date"), "name", repo.Name) slog.Info(gotext.Get("Repository up to date"), "name", repo.Name)
} else if err != nil { }
err = w.Checkout(&git.CheckoutOptions{
Hash: plumbing.NewHash(revHash.String()),
Force: true,
})
if err != nil {
return err return err
} }
repoFS = w.Filesystem repoFS = w.Filesystem
// Make sure the DB is created even if the repo is up to date
if !errors.Is(err, git.NoErrAlreadyUpToDate) || rs.db.IsEmpty(ctx) {
new, err := r.Head() new, err := r.Head()
if err != nil { if err != nil {
return err return err
@@ -127,7 +144,6 @@ func (rs *Repos) Pull(ctx context.Context, repos []types.Repo) error {
return err return err
} }
} }
}
} else { } else {
err = os.RemoveAll(repoDir) err = os.RemoveAll(repoDir)
if err != nil { if err != nil {
@@ -139,9 +155,40 @@ func (rs *Repos) Pull(ctx context.Context, repos []types.Repo) error {
return err return err
} }
_, err = git.PlainCloneContext(ctx, repoDir, false, &git.CloneOptions{ r, err := git.PlainInit(repoDir, false)
URL: repoURL.String(), if err != nil {
return err
}
_, err = r.CreateRemote(&gitConfig.RemoteConfig{
Name: git.DefaultRemoteName,
URLs: []string{repoURL.String()},
})
if err != nil {
return err
}
err = r.FetchContext(ctx, &git.FetchOptions{
Progress: os.Stderr, Progress: os.Stderr,
Force: true,
})
if err != nil {
return err
}
w, err := r.Worktree()
if err != nil {
return err
}
revHash, err := resolveHash(r, repo.Ref)
if err != nil {
return fmt.Errorf("error resolving hash: %w", err)
}
err = w.Checkout(&git.CheckoutOptions{
Hash: plumbing.NewHash(revHash.String()),
Force: true,
}) })
if err != nil { if err != nil {
return err return err
@@ -268,7 +315,8 @@ func (rs *Repos) processRepoChangesRunner(repoDir, scriptDir string) (*interp.Ru
interp.StatHandler(handlers.RestrictedStat(repoDir)), interp.StatHandler(handlers.RestrictedStat(repoDir)),
interp.OpenHandler(handlers.RestrictedOpen(repoDir)), interp.OpenHandler(handlers.RestrictedOpen(repoDir)),
interp.StdIO(handlers.NopRWC{}, handlers.NopRWC{}, handlers.NopRWC{}), interp.StdIO(handlers.NopRWC{}, handlers.NopRWC{}, handlers.NopRWC{}),
interp.Dir(scriptDir), // Use temp dir instead script dir because runner may be for deleted file
interp.Dir(os.TempDir()),
) )
} }
@@ -285,7 +333,7 @@ func (rs *Repos) processRepoChanges(ctx context.Context, repo types.Repo, r *git
patch, err := oldCommit.Patch(newCommit) patch, err := oldCommit.Patch(newCommit)
if err != nil { if err != nil {
return err return fmt.Errorf("error to create patch: %w", err)
} }
var actions []action var actions []action
@@ -319,6 +367,7 @@ func (rs *Repos) processRepoChanges(ctx context.Context, repo types.Repo, r *git
}, },
) )
default: default:
slog.Debug("unexpected, but I'll try to do")
actions = append(actions, action{ actions = append(actions, action{
Type: actionUpdate, Type: actionUpdate,
File: to.Path(), File: to.Path(),
@@ -332,7 +381,7 @@ func (rs *Repos) processRepoChanges(ctx context.Context, repo types.Repo, r *git
for _, action := range actions { for _, action := range actions {
runner, err := rs.processRepoChangesRunner(repoDir, filepath.Dir(filepath.Join(repoDir, action.File))) runner, err := rs.processRepoChangesRunner(repoDir, filepath.Dir(filepath.Join(repoDir, action.File)))
if err != nil { if err != nil {
return err return fmt.Errorf("error creating process repo changes runner: %w", err)
} }
switch action.Type { switch action.Type {
@@ -340,7 +389,6 @@ func (rs *Repos) processRepoChanges(ctx context.Context, repo types.Repo, r *git
if filepath.Base(action.File) != "alr.sh" { if filepath.Base(action.File) != "alr.sh" {
continue continue
} }
scriptFl, err := oldCommit.File(action.File) scriptFl, err := oldCommit.File(action.File)
if err != nil { if err != nil {
return nil return nil
@@ -378,7 +426,7 @@ func (rs *Repos) processRepoChanges(ctx context.Context, repo types.Repo, r *git
err = rs.updatePkg(ctx, repo, runner, r) err = rs.updatePkg(ctx, repo, runner, r)
if err != nil { if err != nil {
return err return fmt.Errorf("error updatePkg: %w", err)
} }
} }
} }

View File

@@ -18,12 +18,18 @@ package repos
import ( import (
"context" "context"
"fmt"
"io" "io"
"path/filepath" "path/filepath"
"reflect" "reflect"
"strings" "strings"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/format/diff" "github.com/go-git/go-git/v5/plumbing/format/diff"
"github.com/go-git/go-git/v5/plumbing/transport"
"github.com/go-git/go-git/v5/plumbing/transport/client"
"mvdan.cc/sh/v3/interp" "mvdan.cc/sh/v3/interp"
"mvdan.cc/sh/v3/syntax" "mvdan.cc/sh/v3/syntax"
@@ -137,3 +143,59 @@ func resolveOverrides(runner *interp.Runner, pkg *db.Package) {
} }
} }
} }
func getHeadReference(r *git.Repository) (plumbing.ReferenceName, error) {
remote, err := r.Remote(git.DefaultRemoteName)
if err != nil {
return "", err
}
endpoint, err := transport.NewEndpoint(remote.Config().URLs[0])
if err != nil {
return "", err
}
gitClient, err := client.NewClient(endpoint)
if err != nil {
return "", err
}
session, err := gitClient.NewUploadPackSession(endpoint, nil)
if err != nil {
return "", err
}
info, err := session.AdvertisedReferences()
if err != nil {
return "", err
}
refs, err := info.AllReferences()
if err != nil {
return "", err
}
return refs["HEAD"].Target(), nil
}
func resolveHash(r *git.Repository, ref string) (*plumbing.Hash, error) {
var err error
if ref == "" {
reference, err := getHeadReference(r)
if err != nil {
return nil, fmt.Errorf("failed to get head reference %w", err)
}
ref = reference.Short()
}
hsh, err := r.ResolveRevision(git.DefaultRemoteName + "/" + plumbing.Revision(ref))
if err != nil {
hsh, err = r.ResolveRevision(plumbing.Revision(ref))
if err != nil {
return nil, err
}
}
return hsh, nil
}

16
repo.go
View File

@@ -52,11 +52,7 @@ func AddRepoCmd() *cli.Command {
Usage: gotext.Get("URL of the new repo"), Usage: gotext.Get("URL of the new repo"),
}, },
}, },
Action: func(c *cli.Context) error { Action: utils.RootNeededAction(func(c *cli.Context) error {
if err := utils.ExitIfNotRoot(); err != nil {
return err
}
name := c.String("name") name := c.String("name")
repoURL := c.String("url") repoURL := c.String("url")
@@ -106,7 +102,7 @@ func AddRepoCmd() *cli.Command {
defer deps.Defer() defer deps.Defer()
return nil return nil
}, }),
} }
} }
@@ -123,11 +119,7 @@ func RemoveRepoCmd() *cli.Command {
Usage: gotext.Get("Name of the repo to be deleted"), Usage: gotext.Get("Name of the repo to be deleted"),
}, },
}, },
Action: func(c *cli.Context) error { Action: utils.RootNeededAction(func(c *cli.Context) error {
if err := utils.ExitIfNotRoot(); err != nil {
return err
}
ctx := c.Context ctx := c.Context
name := c.String("name") name := c.String("name")
@@ -187,7 +179,7 @@ func RemoveRepoCmd() *cli.Command {
} }
return nil return nil
}, }),
} }
} }

View File

@@ -53,11 +53,7 @@ func UpgradeCmd() *cli.Command {
Usage: gotext.Get("Build package from scratch even if there's an already built package available"), Usage: gotext.Get("Build package from scratch even if there's an already built package available"),
}, },
}, },
Action: func(c *cli.Context) error { Action: utils.RootNeededAction(func(c *cli.Context) error {
if err := utils.ExitIfNotRoot(); err != nil {
return err
}
if err := utils.ExitIfCantDropCapsToAlrUser(); err != nil { if err := utils.ExitIfCantDropCapsToAlrUser(); err != nil {
return err return err
} }
@@ -130,7 +126,7 @@ func UpgradeCmd() *cli.Command {
} }
return nil return nil
}, }),
} }
} }