mirror of https://github.com/go-gitea/gitea.git
Move archive function to repo_model and gitrepo (#35514)
parent
cdc0733047
commit
ad2ff67343
@ -1,7 +1,7 @@
|
|||||||
// Copyright 2025 The Gitea Authors. All rights reserved.
|
// Copyright 2025 The Gitea Authors. All rights reserved.
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
package git
|
package repo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
@ -1,75 +0,0 @@
|
|||||||
// Copyright 2015 The Gogs Authors. All rights reserved.
|
|
||||||
// Copyright 2020 The Gitea Authors. All rights reserved.
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
package git
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/git/gitcmd"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ArchiveType archive types
|
|
||||||
type ArchiveType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
ArchiveUnknown ArchiveType = iota
|
|
||||||
ArchiveZip // 1
|
|
||||||
ArchiveTarGz // 2
|
|
||||||
ArchiveBundle // 3
|
|
||||||
)
|
|
||||||
|
|
||||||
// String converts an ArchiveType to string: the extension of the archive file without prefix dot
|
|
||||||
func (a ArchiveType) String() string {
|
|
||||||
switch a {
|
|
||||||
case ArchiveZip:
|
|
||||||
return "zip"
|
|
||||||
case ArchiveTarGz:
|
|
||||||
return "tar.gz"
|
|
||||||
case ArchiveBundle:
|
|
||||||
return "bundle"
|
|
||||||
}
|
|
||||||
return "unknown"
|
|
||||||
}
|
|
||||||
|
|
||||||
func SplitArchiveNameType(s string) (string, ArchiveType) {
|
|
||||||
switch {
|
|
||||||
case strings.HasSuffix(s, ".zip"):
|
|
||||||
return strings.TrimSuffix(s, ".zip"), ArchiveZip
|
|
||||||
case strings.HasSuffix(s, ".tar.gz"):
|
|
||||||
return strings.TrimSuffix(s, ".tar.gz"), ArchiveTarGz
|
|
||||||
case strings.HasSuffix(s, ".bundle"):
|
|
||||||
return strings.TrimSuffix(s, ".bundle"), ArchiveBundle
|
|
||||||
}
|
|
||||||
return s, ArchiveUnknown
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateArchive create archive content to the target path
|
|
||||||
func (repo *Repository) CreateArchive(ctx context.Context, format ArchiveType, target io.Writer, usePrefix bool, commitID string) error {
|
|
||||||
if format.String() == "unknown" {
|
|
||||||
return fmt.Errorf("unknown format: %v", format)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := gitcmd.NewCommand("archive")
|
|
||||||
if usePrefix {
|
|
||||||
cmd.AddOptionFormat("--prefix=%s", filepath.Base(strings.TrimSuffix(repo.Path, ".git"))+"/")
|
|
||||||
}
|
|
||||||
cmd.AddOptionFormat("--format=%s", format.String())
|
|
||||||
cmd.AddDynamicArguments(commitID)
|
|
||||||
|
|
||||||
var stderr strings.Builder
|
|
||||||
err := cmd.Run(ctx, &gitcmd.RunOpts{
|
|
||||||
Dir: repo.Path,
|
|
||||||
Stdout: target,
|
|
||||||
Stderr: &stderr,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return gitcmd.ConcatenateError(err, stderr.String())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -0,0 +1,81 @@
|
|||||||
|
// Copyright 2025 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package gitrepo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/git/gitcmd"
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateArchive create archive content to the target path
|
||||||
|
func CreateArchive(ctx context.Context, repo Repository, format string, target io.Writer, usePrefix bool, commitID string) error {
|
||||||
|
if format == "unknown" {
|
||||||
|
return fmt.Errorf("unknown format: %v", format)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := gitcmd.NewCommand("archive")
|
||||||
|
if usePrefix {
|
||||||
|
cmd.AddOptionFormat("--prefix=%s", filepath.Base(strings.TrimSuffix(repo.RelativePath(), ".git"))+"/")
|
||||||
|
}
|
||||||
|
cmd.AddOptionFormat("--format=%s", format)
|
||||||
|
cmd.AddDynamicArguments(commitID)
|
||||||
|
|
||||||
|
var stderr strings.Builder
|
||||||
|
err := cmd.Run(ctx, &gitcmd.RunOpts{
|
||||||
|
Dir: repoPath(repo),
|
||||||
|
Stdout: target,
|
||||||
|
Stderr: &stderr,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return gitcmd.ConcatenateError(err, stderr.String())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateBundle create bundle content to the target path
|
||||||
|
func CreateBundle(ctx context.Context, repo Repository, commit string, out io.Writer) error {
|
||||||
|
tmp, cleanup, err := setting.AppDataTempDir("git-repo-content").MkdirTempRandom("gitea-bundle")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer cleanup()
|
||||||
|
|
||||||
|
env := append(os.Environ(), "GIT_OBJECT_DIRECTORY="+filepath.Join(repoPath(repo), "objects"))
|
||||||
|
_, _, err = gitcmd.NewCommand("init", "--bare").RunStdString(ctx, &gitcmd.RunOpts{Dir: tmp, Env: env})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, err = gitcmd.NewCommand("reset", "--soft").AddDynamicArguments(commit).RunStdString(ctx, &gitcmd.RunOpts{Dir: tmp, Env: env})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, err = gitcmd.NewCommand("branch", "-m", "bundle").RunStdString(ctx, &gitcmd.RunOpts{Dir: tmp, Env: env})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpFile := filepath.Join(tmp, "bundle")
|
||||||
|
_, _, err = gitcmd.NewCommand("bundle", "create").AddDynamicArguments(tmpFile, "bundle", "HEAD").RunStdString(ctx, &gitcmd.RunOpts{Dir: tmp, Env: env})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fi, err := os.Open(tmpFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer fi.Close()
|
||||||
|
|
||||||
|
_, err = io.Copy(out, fi)
|
||||||
|
return err
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue