WIP: feat: translation support
Some checks failed
continuous-integration/drone/push Build is failing

See #483
This commit is contained in:
2025-08-19 11:22:52 +02:00
parent 5cf6048ecb
commit a31ec51c24
71 changed files with 804 additions and 796 deletions

View File

@ -3,6 +3,7 @@ package git
import (
"coopcloud.tech/abra/pkg/log"
"github.com/go-git/go-git/v5"
"github.com/leonelquinteros/gotext"
)
// Add adds a file to the git index.
@ -18,7 +19,7 @@ func Add(repoPath, path string, dryRun bool) error {
}
if dryRun {
log.Debugf("dry run: adding %s", path)
log.Debug(gotext.Get("dry run: adding %s", path))
} else {
worktree.Add(path)
}

View File

@ -1,11 +1,13 @@
package git
import (
"errors"
"fmt"
"coopcloud.tech/abra/pkg/log"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/leonelquinteros/gotext"
)
// Check if a branch exists in a repo. Use this and not repository.Branch(),
@ -63,7 +65,7 @@ func GetDefaultBranch(repo *git.Repository, repoPath string) (plumbing.Reference
if !HasBranch(repo, "master") {
if !HasBranch(repo, "main") {
return "", fmt.Errorf("failed to select default branch in %s", repoPath)
return "", errors.New(gotext.Get("failed to select default branch in %s", repoPath))
}
branch = "main"
}
@ -90,11 +92,11 @@ func CheckoutDefaultBranch(repo *git.Repository, repoPath string) (plumbing.Refe
}
if err := worktree.Checkout(checkOutOpts); err != nil {
log.Debugf("failed to check out %s in %s", branch, repoPath)
log.Debug(gotext.Get("failed to check out %s in %s", branch, repoPath))
return branch, err
}
log.Debugf("successfully checked out %v in %s", branch, repoPath)
log.Debug(gotext.Get("successfully checked out %v in %s", branch, repoPath))
return branch, nil
}

View File

@ -2,6 +2,7 @@ package git
import (
"context"
"errors"
"fmt"
"os"
"os/signal"
@ -10,6 +11,7 @@ import (
"coopcloud.tech/abra/pkg/log"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/leonelquinteros/gotext"
)
// gitCloneIgnoreErr checks whether we can ignore a git clone error or not.
@ -44,7 +46,7 @@ func Clone(dir, url string) error {
go func() {
if _, err := os.Stat(dir); os.IsNotExist(err) {
log.Debugf("git clone: %s", url)
log.Debug(gotext.Get("git clone: %s", url))
_, err := git.PlainCloneContext(ctx, dir, false, &git.CloneOptions{
URL: url,
@ -54,16 +56,16 @@ func Clone(dir, url string) error {
})
if err != nil && gitCloneIgnoreErr(err) {
log.Debugf("git clone: %s cloned successfully", dir)
log.Debug(gotext.Get("git clone: %s cloned successfully", dir))
errCh <- nil
}
if err := ctx.Err(); err != nil {
errCh <- fmt.Errorf("git clone %s: cancelled due to interrupt", dir)
errCh <- errors.New(gotext.Get("git clone %s: cancelled due to interrupt", dir))
}
if err != nil {
log.Debug("git clone: main branch failed, attempting master branch")
log.Debug(gotext.Get("git clone: main branch failed, attempting master branch"))
_, err := git.PlainCloneContext(ctx, dir, false, &git.CloneOptions{
URL: url,
@ -73,7 +75,7 @@ func Clone(dir, url string) error {
})
if err != nil && gitCloneIgnoreErr(err) {
log.Debugf("git clone: %s cloned successfully", dir)
log.Debug(gotext.Get("git clone: %s cloned successfully", dir))
errCh <- nil
}
@ -82,9 +84,9 @@ func Clone(dir, url string) error {
}
}
log.Debugf("git clone: %s cloned successfully", dir)
log.Debug(gotext.Get("git clone: %s cloned successfully", dir))
} else {
log.Debugf("git clone: %s already exists", dir)
log.Debug(gotext.Get("git clone: %s already exists", dir))
}
errCh <- nil
@ -95,9 +97,9 @@ func Clone(dir, url string) error {
cancelCtx()
fmt.Println() // NOTE(d1): newline after ^C
if err := os.RemoveAll(dir); err != nil {
return fmt.Errorf("unable to clean up git clone of %s: %s", dir, err)
return errors.New(gotext.Get("unable to clean up git clone of %s: %s", dir, err))
}
return fmt.Errorf("git clone %s: cancelled due to interrupt", dir)
return errors.New(gotext.Get("git clone %s: cancelled due to interrupt", dir))
case err := <-errCh:
return err
}

View File

@ -1,16 +1,17 @@
package git
import (
"fmt"
"errors"
"coopcloud.tech/abra/pkg/log"
"github.com/go-git/go-git/v5"
"github.com/leonelquinteros/gotext"
)
// Commit runs a git commit
func Commit(repoPath, commitMessage string, dryRun bool) error {
if commitMessage == "" {
return fmt.Errorf("no commit message specified?")
return errors.New(gotext.Get("no commit message specified?"))
}
commitRepo, err := git.PlainOpen(repoPath)
@ -38,9 +39,9 @@ func Commit(repoPath, commitMessage string, dryRun bool) error {
if err != nil {
return err
}
log.Debug("git changes commited")
log.Debug(gotext.Get("git changes commited"))
} else {
log.Debug("dry run: no changes commited")
log.Debug(gotext.Get("dry run: no changes commited"))
}
return nil

View File

@ -1,14 +1,16 @@
package git
import (
"fmt"
"errors"
"os"
"github.com/leonelquinteros/gotext"
)
// EnsureGitRepo ensures a git repo .git folder exists
func EnsureGitRepo(repoPath string) error {
if _, err := os.Stat(repoPath); os.IsNotExist(err) {
return fmt.Errorf("no .git directory in %s?", repoPath)
return errors.New(gotext.Get("no .git directory in %s?", repoPath))
}
return nil
}

View File

@ -5,6 +5,7 @@ import (
"os/exec"
"coopcloud.tech/abra/pkg/log"
"github.com/leonelquinteros/gotext"
)
// getGitDiffArgs builds the `git diff` invocation args. It removes the usage
@ -26,7 +27,7 @@ func getGitDiffArgs(repoPath string) []string {
// skips if it cannot find the command on the system.
func DiffUnstaged(path string) error {
if _, err := exec.LookPath("git"); err != nil {
log.Warnf("unable to locate git command, cannot output diff")
log.Warnf(gotext.Get("unable to locate git command, cannot output diff"))
return nil
}

View File

@ -1,40 +1,41 @@
package git
import (
"fmt"
"errors"
"coopcloud.tech/abra/pkg/log"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/object"
"github.com/leonelquinteros/gotext"
)
// Init inits a new repo and commits all the stuff if you want
func Init(repoPath string, commit bool, gitName, gitEmail string) error {
repo, err := git.PlainInit(repoPath, false)
if err != nil {
return fmt.Errorf("git init: %s", err)
return errors.New(gotext.Get("git init: %s", err))
}
if err = SwitchToMain(repo); err != nil {
return fmt.Errorf("git branch rename: %s", err)
return errors.New(gotext.Get("git branch rename: %s", err))
}
log.Debugf("initialised new git repo in %s", repoPath)
log.Debug(gotext.Get("initialised new git repo in %s", repoPath))
if commit {
commitRepo, err := git.PlainOpen(repoPath)
if err != nil {
return fmt.Errorf("git open: %s", err)
return errors.New(gotext.Get("git open: %s", err))
}
commitWorktree, err := commitRepo.Worktree()
if err != nil {
return fmt.Errorf("git worktree: %s", err)
return errors.New(gotext.Get("git worktree: %s", err))
}
if err := commitWorktree.AddWithOptions(&git.AddOptions{All: true}); err != nil {
return fmt.Errorf("git add: %s", err)
return errors.New(gotext.Get("git add: %s", err))
}
var author *object.Signature
@ -43,10 +44,10 @@ func Init(repoPath string, commit bool, gitName, gitEmail string) error {
}
if _, err = commitWorktree.Commit("init", &git.CommitOptions{Author: author}); err != nil {
return fmt.Errorf("git commit: %s", err)
return errors.New(gotext.Get("git commit: %s", err))
}
log.Debugf("init committed all files for new git repo in %s", repoPath)
log.Debug(gotext.Get("init committed all files for new git repo in %s", repoPath))
}
return nil
@ -56,20 +57,20 @@ func Init(repoPath string, commit bool, gitName, gitEmail string) error {
func SwitchToMain(repo *git.Repository) error {
ref := plumbing.NewSymbolicReference(plumbing.HEAD, plumbing.ReferenceName("refs/heads/main"))
if err := repo.Storer.SetReference(ref); err != nil {
return fmt.Errorf("set reference: %s", err)
return errors.New(gotext.Get("set reference: %s", err))
}
cfg, err := repo.Config()
if err != nil {
return fmt.Errorf("repo config: %s", err)
return errors.New(gotext.Get("repo config: %s", err))
}
cfg.Init.DefaultBranch = "main"
if err := repo.SetConfig(cfg); err != nil {
return fmt.Errorf("repo set config: %s", err)
return errors.New(gotext.Get("repo set config: %s", err))
}
log.Debug("set 'main' as the default branch")
log.Debug(gotext.Get("set 'main' as the default branch"))
return nil
}

View File

@ -4,12 +4,13 @@ import (
"coopcloud.tech/abra/pkg/log"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/config"
"github.com/leonelquinteros/gotext"
)
// Push pushes the latest changes & optionally tags to the default remote
func Push(repoDir string, remote string, tags bool, dryRun bool) error {
if dryRun {
log.Debugf("dry run: no git changes pushed in %s", repoDir)
log.Debug(gotext.Get("dry run: no git changes pushed in %s", repoDir))
return nil
}
@ -27,7 +28,7 @@ func Push(repoDir string, remote string, tags bool, dryRun bool) error {
return err
}
log.Debugf("git changes pushed")
log.Debug(gotext.Get("git changes pushed"))
if tags {
opts.RefSpecs = append(opts.RefSpecs, config.RefSpec("+refs/tags/*:refs/tags/*"))
@ -36,7 +37,7 @@ func Push(repoDir string, remote string, tags bool, dryRun bool) error {
return err
}
log.Debugf("git tags pushed")
log.Debug(gotext.Get("git tags pushed"))
}
return nil

View File

@ -2,7 +2,6 @@ package git
import (
"errors"
"fmt"
"io/ioutil"
"os"
"os/user"
@ -13,6 +12,7 @@ import (
"github.com/go-git/go-git/v5"
gitConfigPkg "github.com/go-git/go-git/v5/config"
"github.com/go-git/go-git/v5/plumbing/format/gitignore"
"github.com/leonelquinteros/gotext"
)
// IsClean checks if a repo has unstaged changes
@ -23,12 +23,12 @@ func IsClean(repoPath string) (bool, error) {
return false, git.ErrRepositoryNotExists
}
return false, fmt.Errorf("unable to open %s: %s", repoPath, err)
return false, errors.New(gotext.Get("unable to open %s: %s", repoPath, err))
}
worktree, err := repo.Worktree()
if err != nil {
return false, fmt.Errorf("unable to open worktree of %s: %s", repoPath, err)
return false, errors.New(gotext.Get("unable to open worktree of %s: %s", repoPath, err))
}
patterns, err := GetExcludesFiles()
@ -42,14 +42,14 @@ func IsClean(repoPath string) (bool, error) {
status, err := worktree.Status()
if err != nil {
return false, fmt.Errorf("unable to query status of %s: %s", repoPath, err)
return false, errors.New(gotext.Get("unable to query status of %s: %s", repoPath, err))
}
if status.String() != "" {
noNewline := strings.TrimSuffix(status.String(), "\n")
log.Debugf("git status: %s: %s", repoPath, noNewline)
log.Debug(gotext.Get("git status: %s: %s", repoPath, noNewline))
} else {
log.Debugf("git status: %s: clean", repoPath)
log.Debug(gotext.Get("git status: %s: clean", repoPath))
}
return status.IsClean(), nil
@ -85,7 +85,7 @@ func parseGitConfig() (*gitConfigPkg.Config, error) {
globalGitConfig := filepath.Join(usr.HomeDir, ".gitconfig")
if _, err := os.Stat(globalGitConfig); err != nil {
if os.IsNotExist(err) {
log.Debugf("no %s exists, not reading any global gitignore config", globalGitConfig)
log.Debug(gotext.Get("no %s exists, not reading any global gitignore config", globalGitConfig))
return cfg, nil
}
return cfg, err
@ -127,7 +127,7 @@ func parseExcludesFile(excludesfile string) ([]gitignore.Pattern, error) {
if _, err := os.Stat(excludesfile); err != nil {
if os.IsNotExist(err) {
log.Debugf("no %s exists, skipping reading gitignore paths", excludesfile)
log.Debug(gotext.Get("no %s exists, skipping reading gitignore paths", excludesfile))
return ps, nil
}
return ps, err
@ -146,7 +146,7 @@ func parseExcludesFile(excludesfile string) ([]gitignore.Pattern, error) {
}
}
log.Debugf("read global ignore paths: %s", strings.Join(pathsRaw, " "))
log.Debug(gotext.Get("read global ignore paths: %s", strings.Join(pathsRaw, " ")))
return ps, nil
}

View File

@ -6,12 +6,13 @@ import (
"coopcloud.tech/abra/pkg/log"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/config"
"github.com/leonelquinteros/gotext"
)
// CreateRemote creates a new git remote in a repository
func CreateRemote(repo *git.Repository, name, url string, dryRun bool) error {
if dryRun {
log.Debugf("dry run: remote %s (%s) not created", name, url)
log.Debug(gotext.Get("dry run: remote %s (%s) not created", name, url))
return nil
}