Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Finish archive download
  • Loading branch information
lunny committed Jun 22, 2021
commit 23f057789a7cbd5d237e8f8898acdd8ede25472e
28 changes: 23 additions & 5 deletions models/repo_archiver.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,29 @@ import (

// RepoArchiver represents all archivers
type RepoArchiver struct {
ID int64 `xorm:"pk autoincr"`
RepoID int64
Type git.ArchiveType
RefName string
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"index unique(s)"`
Type git.ArchiveType `xorm:"unique(s)"`
CommitID string `xorm:"VARCHAR(40) unique(s)"`
Name string
CreatedUnix timeutil.TimeStamp `xorm:"INDEX NOT NULL created"`
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX NOT NULL updated"`
}

// GetRepoArchiver get an archiver
func GetRepoArchiver(ctx DBContext, repoID int64, tp git.ArchiveType, commitID string) (*RepoArchiver, error) {
var archiver RepoArchiver
has, err := ctx.e.Where("repo_id=?", repoID).And("`type`=?", tp).And("commit_id=?", commitID).Get(&archiver)
if err != nil {
return nil, err
}
if has {
return &archiver, nil
}
return nil, nil
}

// AddArchiver adds an archiver
func AddArchiver(ctx DBContext, archiver *RepoArchiver) error {
_, err := ctx.e.Insert(archiver)
return err
}
31 changes: 14 additions & 17 deletions modules/git/commit_archive.go → modules/git/repo_archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package git
import (
"context"
"fmt"
"io"
"path/filepath"
"strings"
)
Expand All @@ -33,32 +34,28 @@ func (a ArchiveType) String() string {
return "unknown"
}

// CreateArchiveOpts represents options for creating an archive
type CreateArchiveOpts struct {
Format ArchiveType
Prefix bool
}

// CreateArchive create archive content to the target path
func (c *Commit) CreateArchive(ctx context.Context, target string, opts CreateArchiveOpts) error {
if opts.Format.String() == "unknown" {
return fmt.Errorf("unknown format: %v", opts.Format)
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)
}

args := []string{
"archive",
}
if opts.Prefix {
args = append(args, "--prefix="+filepath.Base(strings.TrimSuffix(c.repo.Path, ".git"))+"/")
if usePrefix {
args = append(args, "--prefix="+filepath.Base(strings.TrimSuffix(repo.Path, ".git"))+"/")
}

args = append(args,
"--format="+opts.Format.String(),
"-o",
target,
c.ID.String(),
"--format="+format.String(),
commitID,
)

_, err := NewCommandContext(ctx, args...).RunInDir(c.repo.Path)
return err
var stderr strings.Builder
err := NewCommandContext(ctx, args...).RunInDirPipeline(repo.Path, target, &stderr)
if err != nil {
return ConcatenateError(err, stderr.String())
}
return nil
}
57 changes: 26 additions & 31 deletions routers/web/repo/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"fmt"
"net/http"
"strings"
"time"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/base"
Expand Down Expand Up @@ -368,7 +367,7 @@ func RedirectDownload(ctx *context.Context) {
// Download an archive of a repository
func Download(ctx *context.Context) {
uri := ctx.Params("*")
aReq, err := archiver_service.NewRequest(ctx.Repo.GitRepo, uri)
aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.RepoID, ctx.Repo.GitRepo, uri)
if err != nil {
ctx.ServerError("archiver_service.NewRequest", err)
return
Expand All @@ -379,41 +378,37 @@ func Download(ctx *context.Context) {
}

downloadName := ctx.Repo.Repository.Name + "-" + aReq.GetArchiveName()
complete := aReq.IsComplete()
if !complete {
aReq = archiver_service.ArchiveRepository(aReq)
complete = aReq.WaitForCompletion(ctx)
}

if complete {
if setting.RepoArchive.ServeDirect {
//If we have a signed url (S3, object storage), redirect to this directly.
u, err := storage.RepoArchives.URL(aReq.GetArchivePath(), downloadName)
if u != nil && err == nil {
ctx.Redirect(u.String())
return
}
}

//If we have matched and access to release or issue
fr, err := storage.RepoArchives.Open(aReq.GetArchivePath())
if err != nil {
ctx.ServerError("Open", err)
if err := archiver_service.ArchiveRepository(aReq); err != nil {
ctx.ServerError("ArchiveRepository", err)
return
}

if setting.RepoArchive.ServeDirect {
//If we have a signed url (S3, object storage), redirect to this directly.
u, err := storage.RepoArchives.URL(aReq.GetArchivePath(), downloadName)
if u != nil && err == nil {
ctx.Redirect(u.String())
return
}
defer fr.Close()
ctx.ServeStream(fr, downloadName)
} else {
ctx.Error(http.StatusNotFound)
}

//If we have matched and access to release or issue
fr, err := storage.RepoArchives.Open(aReq.GetArchivePath())
if err != nil {
ctx.ServerError("Open", err)
return
}
defer fr.Close()
ctx.ServeStream(fr, downloadName)
}

// InitiateDownload will enqueue an archival request, as needed. It may submit
// a request that's already in-progress, but the archiver service will just
// kind of drop it on the floor if this is the case.
func InitiateDownload(ctx *context.Context) {
uri := ctx.Params("*")
aReq, err := archiver_service.NewRequest(ctx.Repo.GitRepo, uri)
aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, uri)
if err != nil {
ctx.ServerError("archiver_service.NewRequest", err)
return
Expand All @@ -423,13 +418,13 @@ func InitiateDownload(ctx *context.Context) {
return
}

complete := aReq.IsComplete()
if !complete {
aReq = archiver_service.ArchiveRepository(aReq)
complete, _ = aReq.TimedWaitForCompletion(ctx, 2*time.Second)
err = archiver_service.ArchiveRepository(aReq)
if err != nil {
ctx.ServerError("archiver_service.ArchiveRepository", err)
return
}

ctx.JSON(http.StatusOK, map[string]interface{}{
"complete": complete,
"complete": true,
})
}
Loading