mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-03 20:36:07 +01:00 
			
		
		
		
	Move archive function to repo_model and gitrepo (#35514)
This commit is contained in:
		@@ -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"
 | 
				
			||||||
@@ -11,7 +11,6 @@ import (
 | 
				
			|||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/models/db"
 | 
						"code.gitea.io/gitea/models/db"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/git"
 | 
					 | 
				
			||||||
	"code.gitea.io/gitea/modules/timeutil"
 | 
						"code.gitea.io/gitea/modules/timeutil"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
						"code.gitea.io/gitea/modules/util"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -27,11 +26,46 @@ const (
 | 
				
			|||||||
	ArchiverReady             // it's ready
 | 
						ArchiverReady             // it's ready
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RepoArchiver represents all archivers
 | 
					// RepoArchiver represents all archivers
 | 
				
			||||||
type RepoArchiver struct { //revive:disable-line:exported
 | 
					type RepoArchiver struct { //revive:disable-line:exported
 | 
				
			||||||
	ID          int64           `xorm:"pk autoincr"`
 | 
						ID          int64       `xorm:"pk autoincr"`
 | 
				
			||||||
	RepoID      int64           `xorm:"index unique(s)"`
 | 
						RepoID      int64       `xorm:"index unique(s)"`
 | 
				
			||||||
	Type        git.ArchiveType `xorm:"unique(s)"`
 | 
						Type        ArchiveType `xorm:"unique(s)"`
 | 
				
			||||||
	Status      ArchiverStatus
 | 
						Status      ArchiverStatus
 | 
				
			||||||
	CommitID    string             `xorm:"VARCHAR(64) unique(s)"`
 | 
						CommitID    string             `xorm:"VARCHAR(64) unique(s)"`
 | 
				
			||||||
	CreatedUnix timeutil.TimeStamp `xorm:"INDEX NOT NULL created"`
 | 
						CreatedUnix timeutil.TimeStamp `xorm:"INDEX NOT NULL created"`
 | 
				
			||||||
@@ -56,15 +90,15 @@ func repoArchiverForRelativePath(relativePath string) (*RepoArchiver, error) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, util.NewInvalidArgumentErrorf("invalid storage path: invalid repo id")
 | 
							return nil, util.NewInvalidArgumentErrorf("invalid storage path: invalid repo id")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	commitID, archiveType := git.SplitArchiveNameType(parts[2])
 | 
						commitID, archiveType := SplitArchiveNameType(parts[2])
 | 
				
			||||||
	if archiveType == git.ArchiveUnknown {
 | 
						if archiveType == ArchiveUnknown {
 | 
				
			||||||
		return nil, util.NewInvalidArgumentErrorf("invalid storage path: invalid archive type")
 | 
							return nil, util.NewInvalidArgumentErrorf("invalid storage path: invalid archive type")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return &RepoArchiver{RepoID: repoID, CommitID: commitID, Type: archiveType}, nil
 | 
						return &RepoArchiver{RepoID: repoID, CommitID: commitID, Type: archiveType}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetRepoArchiver get an archiver
 | 
					// GetRepoArchiver get an archiver
 | 
				
			||||||
func GetRepoArchiver(ctx context.Context, repoID int64, tp git.ArchiveType, commitID string) (*RepoArchiver, error) {
 | 
					func GetRepoArchiver(ctx context.Context, repoID int64, tp ArchiveType, commitID string) (*RepoArchiver, error) {
 | 
				
			||||||
	var archiver RepoArchiver
 | 
						var archiver RepoArchiver
 | 
				
			||||||
	has, err := db.GetEngine(ctx).Where("repo_id=?", repoID).And("`type`=?", tp).And("commit_id=?", commitID).Get(&archiver)
 | 
						has, err := db.GetEngine(ctx).Where("repo_id=?", repoID).And("`type`=?", tp).And("commit_id=?", commitID).Get(&archiver)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,14 +12,12 @@ import (
 | 
				
			|||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"path"
 | 
						"path"
 | 
				
			||||||
	"path/filepath"
 | 
					 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/modules/git/gitcmd"
 | 
						"code.gitea.io/gitea/modules/git/gitcmd"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/proxy"
 | 
						"code.gitea.io/gitea/modules/proxy"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GPGSettings represents the default GPG settings for this repository
 | 
					// GPGSettings represents the default GPG settings for this repository
 | 
				
			||||||
@@ -242,43 +240,3 @@ func GetLatestCommitTime(ctx context.Context, repoPath string) (time.Time, error
 | 
				
			|||||||
	commitTime := strings.TrimSpace(stdout)
 | 
						commitTime := strings.TrimSpace(stdout)
 | 
				
			||||||
	return time.Parse("Mon Jan _2 15:04:05 2006 -0700", commitTime)
 | 
						return time.Parse("Mon Jan _2 15:04:05 2006 -0700", commitTime)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
// CreateBundle create bundle content to the target path
 | 
					 | 
				
			||||||
func (repo *Repository) CreateBundle(ctx context.Context, 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(repo.Path, "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
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										81
									
								
								modules/gitrepo/archive.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								modules/gitrepo/archive.go
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -7,13 +7,13 @@ import (
 | 
				
			|||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/modules/git"
 | 
						repo_model "code.gitea.io/gitea/models/repo"
 | 
				
			||||||
	"code.gitea.io/gitea/services/context"
 | 
						"code.gitea.io/gitea/services/context"
 | 
				
			||||||
	archiver_service "code.gitea.io/gitea/services/repository/archiver"
 | 
						archiver_service "code.gitea.io/gitea/services/repository/archiver"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func serveRepoArchive(ctx *context.APIContext, reqFileName string) {
 | 
					func serveRepoArchive(ctx *context.APIContext, reqFileName string) {
 | 
				
			||||||
	aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, reqFileName)
 | 
						aReq, err := archiver_service.NewRequest(ctx.Repo.Repository, ctx.Repo.GitRepo, reqFileName)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		if errors.Is(err, archiver_service.ErrUnknownArchiveFormat{}) {
 | 
							if errors.Is(err, archiver_service.ErrUnknownArchiveFormat{}) {
 | 
				
			||||||
			ctx.APIError(http.StatusBadRequest, err)
 | 
								ctx.APIError(http.StatusBadRequest, err)
 | 
				
			||||||
@@ -24,18 +24,18 @@ func serveRepoArchive(ctx *context.APIContext, reqFileName string) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	archiver_service.ServeRepoArchive(ctx.Base, ctx.Repo.Repository, ctx.Repo.GitRepo, aReq)
 | 
						archiver_service.ServeRepoArchive(ctx.Base, aReq)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func DownloadArchive(ctx *context.APIContext) {
 | 
					func DownloadArchive(ctx *context.APIContext) {
 | 
				
			||||||
	var tp git.ArchiveType
 | 
						var tp repo_model.ArchiveType
 | 
				
			||||||
	switch ballType := ctx.PathParam("ball_type"); ballType {
 | 
						switch ballType := ctx.PathParam("ball_type"); ballType {
 | 
				
			||||||
	case "tarball":
 | 
						case "tarball":
 | 
				
			||||||
		tp = git.ArchiveTarGz
 | 
							tp = repo_model.ArchiveTarGz
 | 
				
			||||||
	case "zipball":
 | 
						case "zipball":
 | 
				
			||||||
		tp = git.ArchiveZip
 | 
							tp = repo_model.ArchiveZip
 | 
				
			||||||
	case "bundle":
 | 
						case "bundle":
 | 
				
			||||||
		tp = git.ArchiveBundle
 | 
							tp = repo_model.ArchiveBundle
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		ctx.APIError(http.StatusBadRequest, "Unknown archive type: "+ballType)
 | 
							ctx.APIError(http.StatusBadRequest, "Unknown archive type: "+ballType)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -364,7 +364,7 @@ func RedirectDownload(ctx *context.Context) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Download an archive of a repository
 | 
					// Download an archive of a repository
 | 
				
			||||||
func Download(ctx *context.Context) {
 | 
					func Download(ctx *context.Context) {
 | 
				
			||||||
	aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.PathParam("*"))
 | 
						aReq, err := archiver_service.NewRequest(ctx.Repo.Repository, ctx.Repo.GitRepo, ctx.PathParam("*"))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		if errors.Is(err, archiver_service.ErrUnknownArchiveFormat{}) {
 | 
							if errors.Is(err, archiver_service.ErrUnknownArchiveFormat{}) {
 | 
				
			||||||
			ctx.HTTPError(http.StatusBadRequest, err.Error())
 | 
								ctx.HTTPError(http.StatusBadRequest, err.Error())
 | 
				
			||||||
@@ -375,7 +375,7 @@ func Download(ctx *context.Context) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	archiver_service.ServeRepoArchive(ctx.Base, ctx.Repo.Repository, ctx.Repo.GitRepo, aReq)
 | 
						archiver_service.ServeRepoArchive(ctx.Base, aReq)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// InitiateDownload will enqueue an archival request, as needed.  It may submit
 | 
					// InitiateDownload will enqueue an archival request, as needed.  It may submit
 | 
				
			||||||
@@ -388,7 +388,7 @@ func InitiateDownload(ctx *context.Context) {
 | 
				
			|||||||
		})
 | 
							})
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.PathParam("*"))
 | 
						aReq, err := archiver_service.NewRequest(ctx.Repo.Repository, ctx.Repo.GitRepo, ctx.PathParam("*"))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		ctx.HTTPError(http.StatusBadRequest, "invalid archive request")
 | 
							ctx.HTTPError(http.StatusBadRequest, "invalid archive request")
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
@@ -398,7 +398,7 @@ func InitiateDownload(ctx *context.Context) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	archiver, err := repo_model.GetRepoArchiver(ctx, aReq.RepoID, aReq.Type, aReq.CommitID)
 | 
						archiver, err := repo_model.GetRepoArchiver(ctx, aReq.Repo.ID, aReq.Type, aReq.CommitID)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		ctx.ServerError("archiver_service.StartArchive", err)
 | 
							ctx.ServerError("archiver_service.StartArchive", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,8 +33,8 @@ import (
 | 
				
			|||||||
// This is entirely opaque to external entities, though, and mostly used as a
 | 
					// This is entirely opaque to external entities, though, and mostly used as a
 | 
				
			||||||
// handle elsewhere.
 | 
					// handle elsewhere.
 | 
				
			||||||
type ArchiveRequest struct {
 | 
					type ArchiveRequest struct {
 | 
				
			||||||
	RepoID   int64
 | 
						Repo     *repo_model.Repository
 | 
				
			||||||
	Type     git.ArchiveType
 | 
						Type     repo_model.ArchiveType
 | 
				
			||||||
	CommitID string
 | 
						CommitID string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	archiveRefShortName string // the ref short name to download the archive, for example: "master", "v1.0.0", "commit id"
 | 
						archiveRefShortName string // the ref short name to download the archive, for example: "master", "v1.0.0", "commit id"
 | 
				
			||||||
@@ -74,20 +74,20 @@ func (e RepoRefNotFoundError) Is(err error) bool {
 | 
				
			|||||||
// NewRequest creates an archival request, based on the URI.  The
 | 
					// NewRequest creates an archival request, based on the URI.  The
 | 
				
			||||||
// resulting ArchiveRequest is suitable for being passed to Await()
 | 
					// resulting ArchiveRequest is suitable for being passed to Await()
 | 
				
			||||||
// if it's determined that the request still needs to be satisfied.
 | 
					// if it's determined that the request still needs to be satisfied.
 | 
				
			||||||
func NewRequest(repoID int64, repo *git.Repository, archiveRefExt string) (*ArchiveRequest, error) {
 | 
					func NewRequest(repo *repo_model.Repository, gitRepo *git.Repository, archiveRefExt string) (*ArchiveRequest, error) {
 | 
				
			||||||
	// here the archiveRefShortName is not a clear ref, it could be a tag, branch or commit id
 | 
						// here the archiveRefShortName is not a clear ref, it could be a tag, branch or commit id
 | 
				
			||||||
	archiveRefShortName, archiveType := git.SplitArchiveNameType(archiveRefExt)
 | 
						archiveRefShortName, archiveType := repo_model.SplitArchiveNameType(archiveRefExt)
 | 
				
			||||||
	if archiveType == git.ArchiveUnknown {
 | 
						if archiveType == repo_model.ArchiveUnknown {
 | 
				
			||||||
		return nil, ErrUnknownArchiveFormat{archiveRefExt}
 | 
							return nil, ErrUnknownArchiveFormat{archiveRefExt}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Get corresponding commit.
 | 
						// Get corresponding commit.
 | 
				
			||||||
	commitID, err := repo.ConvertToGitID(archiveRefShortName)
 | 
						commitID, err := gitRepo.ConvertToGitID(archiveRefShortName)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, RepoRefNotFoundError{RefShortName: archiveRefShortName}
 | 
							return nil, RepoRefNotFoundError{RefShortName: archiveRefShortName}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	r := &ArchiveRequest{RepoID: repoID, archiveRefShortName: archiveRefShortName, Type: archiveType}
 | 
						r := &ArchiveRequest{Repo: repo, archiveRefShortName: archiveRefShortName, Type: archiveType}
 | 
				
			||||||
	r.CommitID = commitID.String()
 | 
						r.CommitID = commitID.String()
 | 
				
			||||||
	return r, nil
 | 
						return r, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -105,7 +105,7 @@ func (aReq *ArchiveRequest) GetArchiveName() string {
 | 
				
			|||||||
// context is cancelled/times out a started archiver will still continue to run
 | 
					// context is cancelled/times out a started archiver will still continue to run
 | 
				
			||||||
// in the background.
 | 
					// in the background.
 | 
				
			||||||
func (aReq *ArchiveRequest) Await(ctx context.Context) (*repo_model.RepoArchiver, error) {
 | 
					func (aReq *ArchiveRequest) Await(ctx context.Context) (*repo_model.RepoArchiver, error) {
 | 
				
			||||||
	archiver, err := repo_model.GetRepoArchiver(ctx, aReq.RepoID, aReq.Type, aReq.CommitID)
 | 
						archiver, err := repo_model.GetRepoArchiver(ctx, aReq.Repo.ID, aReq.Type, aReq.CommitID)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("models.GetRepoArchiver: %w", err)
 | 
							return nil, fmt.Errorf("models.GetRepoArchiver: %w", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -130,7 +130,7 @@ func (aReq *ArchiveRequest) Await(ctx context.Context) (*repo_model.RepoArchiver
 | 
				
			|||||||
		case <-ctx.Done():
 | 
							case <-ctx.Done():
 | 
				
			||||||
			return nil, ctx.Err()
 | 
								return nil, ctx.Err()
 | 
				
			||||||
		case <-poll.C:
 | 
							case <-poll.C:
 | 
				
			||||||
			archiver, err = repo_model.GetRepoArchiver(ctx, aReq.RepoID, aReq.Type, aReq.CommitID)
 | 
								archiver, err = repo_model.GetRepoArchiver(ctx, aReq.Repo.ID, aReq.Type, aReq.CommitID)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return nil, fmt.Errorf("repo_model.GetRepoArchiver: %w", err)
 | 
									return nil, fmt.Errorf("repo_model.GetRepoArchiver: %w", err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -143,17 +143,19 @@ func (aReq *ArchiveRequest) Await(ctx context.Context) (*repo_model.RepoArchiver
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Stream satisfies the ArchiveRequest being passed in.  Processing
 | 
					// Stream satisfies the ArchiveRequest being passed in.  Processing
 | 
				
			||||||
// will occur directly in this routine.
 | 
					// will occur directly in this routine.
 | 
				
			||||||
func (aReq *ArchiveRequest) Stream(ctx context.Context, gitRepo *git.Repository, w io.Writer) error {
 | 
					func (aReq *ArchiveRequest) Stream(ctx context.Context, w io.Writer) error {
 | 
				
			||||||
	if aReq.Type == git.ArchiveBundle {
 | 
						if aReq.Type == repo_model.ArchiveBundle {
 | 
				
			||||||
		return gitRepo.CreateBundle(
 | 
							return gitrepo.CreateBundle(
 | 
				
			||||||
			ctx,
 | 
								ctx,
 | 
				
			||||||
 | 
								aReq.Repo,
 | 
				
			||||||
			aReq.CommitID,
 | 
								aReq.CommitID,
 | 
				
			||||||
			w,
 | 
								w,
 | 
				
			||||||
		)
 | 
							)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return gitRepo.CreateArchive(
 | 
						return gitrepo.CreateArchive(
 | 
				
			||||||
		ctx,
 | 
							ctx,
 | 
				
			||||||
		aReq.Type,
 | 
							aReq.Repo,
 | 
				
			||||||
 | 
							aReq.Type.String(),
 | 
				
			||||||
		w,
 | 
							w,
 | 
				
			||||||
		setting.Repository.PrefixArchiveFiles,
 | 
							setting.Repository.PrefixArchiveFiles,
 | 
				
			||||||
		aReq.CommitID,
 | 
							aReq.CommitID,
 | 
				
			||||||
@@ -167,10 +169,10 @@ func (aReq *ArchiveRequest) Stream(ctx context.Context, gitRepo *git.Repository,
 | 
				
			|||||||
// being returned for completion, as it may be different than the one they passed
 | 
					// being returned for completion, as it may be different than the one they passed
 | 
				
			||||||
// in.
 | 
					// in.
 | 
				
			||||||
func doArchive(ctx context.Context, r *ArchiveRequest) (*repo_model.RepoArchiver, error) {
 | 
					func doArchive(ctx context.Context, r *ArchiveRequest) (*repo_model.RepoArchiver, error) {
 | 
				
			||||||
	ctx, _, finished := process.GetManager().AddContext(ctx, fmt.Sprintf("ArchiveRequest[%d]: %s", r.RepoID, r.GetArchiveName()))
 | 
						ctx, _, finished := process.GetManager().AddContext(ctx, fmt.Sprintf("ArchiveRequest[%s]: %s", r.Repo.FullName(), r.GetArchiveName()))
 | 
				
			||||||
	defer finished()
 | 
						defer finished()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	archiver, err := repo_model.GetRepoArchiver(ctx, r.RepoID, r.Type, r.CommitID)
 | 
						archiver, err := repo_model.GetRepoArchiver(ctx, r.Repo.ID, r.Type, r.CommitID)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -183,7 +185,7 @@ func doArchive(ctx context.Context, r *ArchiveRequest) (*repo_model.RepoArchiver
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		archiver = &repo_model.RepoArchiver{
 | 
							archiver = &repo_model.RepoArchiver{
 | 
				
			||||||
			RepoID:   r.RepoID,
 | 
								RepoID:   r.Repo.ID,
 | 
				
			||||||
			Type:     r.Type,
 | 
								Type:     r.Type,
 | 
				
			||||||
			CommitID: r.CommitID,
 | 
								CommitID: r.CommitID,
 | 
				
			||||||
			Status:   repo_model.ArchiverGenerating,
 | 
								Status:   repo_model.ArchiverGenerating,
 | 
				
			||||||
@@ -215,28 +217,18 @@ func doArchive(ctx context.Context, r *ArchiveRequest) (*repo_model.RepoArchiver
 | 
				
			|||||||
		_ = rd.Close()
 | 
							_ = rd.Close()
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
	done := make(chan error, 1) // Ensure that there is some capacity which will ensure that the goroutine below can always finish
 | 
						done := make(chan error, 1) // Ensure that there is some capacity which will ensure that the goroutine below can always finish
 | 
				
			||||||
	repo, err := repo_model.GetRepositoryByID(ctx, archiver.RepoID)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, fmt.Errorf("archiver.LoadRepo failed: %w", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gitRepo, err := gitrepo.OpenRepository(ctx, repo)
 | 
						go func(done chan error, w *io.PipeWriter, archiveReq *ArchiveRequest) {
 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer gitRepo.Close()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	go func(done chan error, w *io.PipeWriter, archiveReq *ArchiveRequest, gitRepo *git.Repository) {
 | 
					 | 
				
			||||||
		defer func() {
 | 
							defer func() {
 | 
				
			||||||
			if r := recover(); r != nil {
 | 
								if r := recover(); r != nil {
 | 
				
			||||||
				done <- fmt.Errorf("%v", r)
 | 
									done <- fmt.Errorf("%v", r)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}()
 | 
							}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		err := archiveReq.Stream(ctx, gitRepo, w)
 | 
							err := archiveReq.Stream(ctx, w)
 | 
				
			||||||
		_ = w.CloseWithError(err)
 | 
							_ = w.CloseWithError(err)
 | 
				
			||||||
		done <- err
 | 
							done <- err
 | 
				
			||||||
	}(done, w, r, gitRepo)
 | 
						}(done, w, r)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// TODO: add lfs data to zip
 | 
						// TODO: add lfs data to zip
 | 
				
			||||||
	// TODO: add submodule data to zip
 | 
						// TODO: add submodule data to zip
 | 
				
			||||||
@@ -347,20 +339,20 @@ func DeleteRepositoryArchives(ctx context.Context) error {
 | 
				
			|||||||
	return storage.Clean(storage.RepoArchives)
 | 
						return storage.Clean(storage.RepoArchives)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func ServeRepoArchive(ctx *gitea_context.Base, repo *repo_model.Repository, gitRepo *git.Repository, archiveReq *ArchiveRequest) {
 | 
					func ServeRepoArchive(ctx *gitea_context.Base, archiveReq *ArchiveRequest) {
 | 
				
			||||||
	// Add nix format link header so tarballs lock correctly:
 | 
						// Add nix format link header so tarballs lock correctly:
 | 
				
			||||||
	// https://github.com/nixos/nix/blob/56763ff918eb308db23080e560ed2ea3e00c80a7/doc/manual/src/protocols/tarball-fetcher.md
 | 
						// https://github.com/nixos/nix/blob/56763ff918eb308db23080e560ed2ea3e00c80a7/doc/manual/src/protocols/tarball-fetcher.md
 | 
				
			||||||
	ctx.Resp.Header().Add("Link", fmt.Sprintf(`<%s/archive/%s.%s?rev=%s>; rel="immutable"`,
 | 
						ctx.Resp.Header().Add("Link", fmt.Sprintf(`<%s/archive/%s.%s?rev=%s>; rel="immutable"`,
 | 
				
			||||||
		repo.APIURL(),
 | 
							archiveReq.Repo.APIURL(),
 | 
				
			||||||
		archiveReq.CommitID,
 | 
							archiveReq.CommitID,
 | 
				
			||||||
		archiveReq.Type.String(),
 | 
							archiveReq.Type.String(),
 | 
				
			||||||
		archiveReq.CommitID,
 | 
							archiveReq.CommitID,
 | 
				
			||||||
	))
 | 
						))
 | 
				
			||||||
	downloadName := repo.Name + "-" + archiveReq.GetArchiveName()
 | 
						downloadName := archiveReq.Repo.Name + "-" + archiveReq.GetArchiveName()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if setting.Repository.StreamArchives {
 | 
						if setting.Repository.StreamArchives {
 | 
				
			||||||
		httplib.ServeSetHeaders(ctx.Resp, &httplib.ServeHeaderOptions{Filename: downloadName})
 | 
							httplib.ServeSetHeaders(ctx.Resp, &httplib.ServeHeaderOptions{Filename: downloadName})
 | 
				
			||||||
		if err := archiveReq.Stream(ctx, gitRepo, ctx.Resp); err != nil && !ctx.Written() {
 | 
							if err := archiveReq.Stream(ctx, ctx.Resp); err != nil && !ctx.Written() {
 | 
				
			||||||
			log.Error("Archive %v streaming failed: %v", archiveReq, err)
 | 
								log.Error("Archive %v streaming failed: %v", archiveReq, err)
 | 
				
			||||||
			ctx.HTTPError(http.StatusInternalServerError)
 | 
								ctx.HTTPError(http.StatusInternalServerError)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,47 +29,47 @@ func TestArchive_Basic(t *testing.T) {
 | 
				
			|||||||
	contexttest.LoadGitRepo(t, ctx)
 | 
						contexttest.LoadGitRepo(t, ctx)
 | 
				
			||||||
	defer ctx.Repo.GitRepo.Close()
 | 
						defer ctx.Repo.GitRepo.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bogusReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".zip")
 | 
						bogusReq, err := NewRequest(ctx.Repo.Repository, ctx.Repo.GitRepo, firstCommit+".zip")
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
	assert.NotNil(t, bogusReq)
 | 
						assert.NotNil(t, bogusReq)
 | 
				
			||||||
	assert.Equal(t, firstCommit+".zip", bogusReq.GetArchiveName())
 | 
						assert.Equal(t, firstCommit+".zip", bogusReq.GetArchiveName())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Check a series of bogus requests.
 | 
						// Check a series of bogus requests.
 | 
				
			||||||
	// Step 1, valid commit with a bad extension.
 | 
						// Step 1, valid commit with a bad extension.
 | 
				
			||||||
	bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".unknown")
 | 
						bogusReq, err = NewRequest(ctx.Repo.Repository, ctx.Repo.GitRepo, firstCommit+".unknown")
 | 
				
			||||||
	assert.Error(t, err)
 | 
						assert.Error(t, err)
 | 
				
			||||||
	assert.Nil(t, bogusReq)
 | 
						assert.Nil(t, bogusReq)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Step 2, missing commit.
 | 
						// Step 2, missing commit.
 | 
				
			||||||
	bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "dbffff.zip")
 | 
						bogusReq, err = NewRequest(ctx.Repo.Repository, ctx.Repo.GitRepo, "dbffff.zip")
 | 
				
			||||||
	assert.Error(t, err)
 | 
						assert.Error(t, err)
 | 
				
			||||||
	assert.Nil(t, bogusReq)
 | 
						assert.Nil(t, bogusReq)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Step 3, doesn't look like branch/tag/commit.
 | 
						// Step 3, doesn't look like branch/tag/commit.
 | 
				
			||||||
	bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "db.zip")
 | 
						bogusReq, err = NewRequest(ctx.Repo.Repository, ctx.Repo.GitRepo, "db.zip")
 | 
				
			||||||
	assert.Error(t, err)
 | 
						assert.Error(t, err)
 | 
				
			||||||
	assert.Nil(t, bogusReq)
 | 
						assert.Nil(t, bogusReq)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "master.zip")
 | 
						bogusReq, err = NewRequest(ctx.Repo.Repository, ctx.Repo.GitRepo, "master.zip")
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
	assert.NotNil(t, bogusReq)
 | 
						assert.NotNil(t, bogusReq)
 | 
				
			||||||
	assert.Equal(t, "master.zip", bogusReq.GetArchiveName())
 | 
						assert.Equal(t, "master.zip", bogusReq.GetArchiveName())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "test/archive.zip")
 | 
						bogusReq, err = NewRequest(ctx.Repo.Repository, ctx.Repo.GitRepo, "test/archive.zip")
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
	assert.NotNil(t, bogusReq)
 | 
						assert.NotNil(t, bogusReq)
 | 
				
			||||||
	assert.Equal(t, "test-archive.zip", bogusReq.GetArchiveName())
 | 
						assert.Equal(t, "test-archive.zip", bogusReq.GetArchiveName())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Now two valid requests, firstCommit with valid extensions.
 | 
						// Now two valid requests, firstCommit with valid extensions.
 | 
				
			||||||
	zipReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".zip")
 | 
						zipReq, err := NewRequest(ctx.Repo.Repository, ctx.Repo.GitRepo, firstCommit+".zip")
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
	assert.NotNil(t, zipReq)
 | 
						assert.NotNil(t, zipReq)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tgzReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".tar.gz")
 | 
						tgzReq, err := NewRequest(ctx.Repo.Repository, ctx.Repo.GitRepo, firstCommit+".tar.gz")
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
	assert.NotNil(t, tgzReq)
 | 
						assert.NotNil(t, tgzReq)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	secondReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, secondCommit+".bundle")
 | 
						secondReq, err := NewRequest(ctx.Repo.Repository, ctx.Repo.GitRepo, secondCommit+".bundle")
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
	assert.NotNil(t, secondReq)
 | 
						assert.NotNil(t, secondReq)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -89,7 +89,7 @@ func TestArchive_Basic(t *testing.T) {
 | 
				
			|||||||
	// Sleep two seconds to make sure the queue doesn't change.
 | 
						// Sleep two seconds to make sure the queue doesn't change.
 | 
				
			||||||
	time.Sleep(2 * time.Second)
 | 
						time.Sleep(2 * time.Second)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	zipReq2, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".zip")
 | 
						zipReq2, err := NewRequest(ctx.Repo.Repository, ctx.Repo.GitRepo, firstCommit+".zip")
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
	// This zipReq should match what's sitting in the queue, as we haven't
 | 
						// This zipReq should match what's sitting in the queue, as we haven't
 | 
				
			||||||
	// let it release yet.  From the consumer's point of view, this looks like
 | 
						// let it release yet.  From the consumer's point of view, this looks like
 | 
				
			||||||
@@ -104,12 +104,12 @@ func TestArchive_Basic(t *testing.T) {
 | 
				
			|||||||
	// Now we'll submit a request and TimedWaitForCompletion twice, before and
 | 
						// Now we'll submit a request and TimedWaitForCompletion twice, before and
 | 
				
			||||||
	// after we release it.  We should trigger both the timeout and non-timeout
 | 
						// after we release it.  We should trigger both the timeout and non-timeout
 | 
				
			||||||
	// cases.
 | 
						// cases.
 | 
				
			||||||
	timedReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, secondCommit+".tar.gz")
 | 
						timedReq, err := NewRequest(ctx.Repo.Repository, ctx.Repo.GitRepo, secondCommit+".tar.gz")
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
	assert.NotNil(t, timedReq)
 | 
						assert.NotNil(t, timedReq)
 | 
				
			||||||
	doArchive(t.Context(), timedReq)
 | 
						doArchive(t.Context(), timedReq)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	zipReq2, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".zip")
 | 
						zipReq2, err = NewRequest(ctx.Repo.Repository, ctx.Repo.GitRepo, firstCommit+".zip")
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
	// Now, we're guaranteed to have released the original zipReq from the queue.
 | 
						// Now, we're guaranteed to have released the original zipReq from the queue.
 | 
				
			||||||
	// Ensure that we don't get handed back the released entry somehow, but they
 | 
						// Ensure that we don't get handed back the released entry somehow, but they
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user