mirror of
https://github.com/go-gitea/gitea
synced 2025-07-22 18:28:37 +00:00
Refactor context RefName and RepoAssignment (#33226)
The `ctx.Repo.RefName` was used to be a "short name", it causes a lot of ambiguity. This PR does some refactoring and use `RefFullName` to replace the legacy `RefName`, and simplify RepoAssignment
This commit is contained in:
@@ -58,10 +58,10 @@ type Repository struct {
|
||||
IsViewTag bool
|
||||
IsViewCommit bool
|
||||
|
||||
RefName string
|
||||
BranchName string
|
||||
TagName string
|
||||
TreePath string
|
||||
RefFullName git.RefName
|
||||
BranchName string
|
||||
TagName string
|
||||
TreePath string
|
||||
|
||||
// Commit it is always set to the commit for the branch or tag
|
||||
Commit *git.Commit
|
||||
@@ -392,33 +392,25 @@ func repoAssignment(ctx *Context, repo *repo_model.Repository) {
|
||||
|
||||
// RepoAssignment returns a middleware to handle repository assignment
|
||||
func RepoAssignment(ctx *Context) {
|
||||
if _, repoAssignmentOnce := ctx.Data["repoAssignmentExecuted"]; repoAssignmentOnce {
|
||||
// FIXME: it should panic in dev/test modes to have a clear behavior
|
||||
if !setting.IsProd || setting.IsInTesting {
|
||||
panic("RepoAssignment should not be executed twice")
|
||||
}
|
||||
return
|
||||
if ctx.Data["Repository"] != nil {
|
||||
setting.PanicInDevOrTesting("RepoAssignment should not be executed twice")
|
||||
}
|
||||
ctx.Data["repoAssignmentExecuted"] = true
|
||||
|
||||
var (
|
||||
owner *user_model.User
|
||||
err error
|
||||
)
|
||||
|
||||
var err error
|
||||
userName := ctx.PathParam("username")
|
||||
repoName := ctx.PathParam("reponame")
|
||||
repoName = strings.TrimSuffix(repoName, ".git")
|
||||
if setting.Other.EnableFeed {
|
||||
ctx.Data["EnableFeed"] = true
|
||||
repoName = strings.TrimSuffix(repoName, ".rss")
|
||||
repoName = strings.TrimSuffix(repoName, ".atom")
|
||||
}
|
||||
|
||||
// Check if the user is the same as the repository owner
|
||||
if ctx.IsSigned && ctx.Doer.LowerName == strings.ToLower(userName) {
|
||||
owner = ctx.Doer
|
||||
ctx.Repo.Owner = ctx.Doer
|
||||
} else {
|
||||
owner, err = user_model.GetUserByName(ctx, userName)
|
||||
ctx.Repo.Owner, err = user_model.GetUserByName(ctx, userName)
|
||||
if err != nil {
|
||||
if user_model.IsErrUserNotExist(err) {
|
||||
// go-get does not support redirects
|
||||
@@ -441,8 +433,7 @@ func RepoAssignment(ctx *Context) {
|
||||
return
|
||||
}
|
||||
}
|
||||
ctx.Repo.Owner = owner
|
||||
ctx.ContextUser = owner
|
||||
ctx.ContextUser = ctx.Repo.Owner
|
||||
ctx.Data["ContextUser"] = ctx.ContextUser
|
||||
|
||||
// redirect link to wiki
|
||||
@@ -466,10 +457,10 @@ func RepoAssignment(ctx *Context) {
|
||||
}
|
||||
|
||||
// Get repository.
|
||||
repo, err := repo_model.GetRepositoryByName(ctx, owner.ID, repoName)
|
||||
repo, err := repo_model.GetRepositoryByName(ctx, ctx.Repo.Owner.ID, repoName)
|
||||
if err != nil {
|
||||
if repo_model.IsErrRepoNotExist(err) {
|
||||
redirectRepoID, err := repo_model.LookupRedirect(ctx, owner.ID, repoName)
|
||||
redirectRepoID, err := repo_model.LookupRedirect(ctx, ctx.Repo.Owner.ID, repoName)
|
||||
if err == nil {
|
||||
RedirectToRepo(ctx.Base, redirectRepoID)
|
||||
} else if repo_model.IsErrRedirectNotExist(err) {
|
||||
@@ -486,7 +477,7 @@ func RepoAssignment(ctx *Context) {
|
||||
}
|
||||
return
|
||||
}
|
||||
repo.Owner = owner
|
||||
repo.Owner = ctx.Repo.Owner
|
||||
|
||||
repoAssignment(ctx, repo)
|
||||
if ctx.Written() {
|
||||
@@ -495,11 +486,7 @@ func RepoAssignment(ctx *Context) {
|
||||
|
||||
ctx.Repo.RepoLink = repo.Link()
|
||||
ctx.Data["RepoLink"] = ctx.Repo.RepoLink
|
||||
|
||||
if setting.Other.EnableFeed {
|
||||
ctx.Data["EnableFeed"] = true
|
||||
ctx.Data["FeedURL"] = ctx.Repo.RepoLink
|
||||
}
|
||||
ctx.Data["FeedURL"] = ctx.Repo.RepoLink
|
||||
|
||||
unit, err := ctx.Repo.Repository.GetUnit(ctx, unit_model.TypeExternalTracker)
|
||||
if err == nil {
|
||||
@@ -526,7 +513,7 @@ func RepoAssignment(ctx *Context) {
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["Title"] = owner.Name + "/" + repo.Name
|
||||
ctx.Data["Title"] = repo.Owner.Name + "/" + repo.Name
|
||||
ctx.Data["Repository"] = repo
|
||||
ctx.Data["Owner"] = ctx.Repo.Repository.Owner
|
||||
ctx.Data["CanWriteCode"] = ctx.Repo.CanWrite(unit_model.TypeCode)
|
||||
@@ -596,7 +583,6 @@ func RepoAssignment(ctx *Context) {
|
||||
|
||||
// Disable everything when the repo is being created
|
||||
if ctx.Repo.Repository.IsBeingCreated() || ctx.Repo.Repository.IsBroken() {
|
||||
ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch
|
||||
if !isHomeOrSettings {
|
||||
ctx.Redirect(ctx.Repo.RepoLink)
|
||||
}
|
||||
@@ -604,9 +590,7 @@ func RepoAssignment(ctx *Context) {
|
||||
}
|
||||
|
||||
if ctx.Repo.GitRepo != nil {
|
||||
if !setting.IsProd || setting.IsInTesting {
|
||||
panic("RepoAssignment: GitRepo should be nil")
|
||||
}
|
||||
setting.PanicInDevOrTesting("RepoAssignment: GitRepo should be nil")
|
||||
_ = ctx.Repo.GitRepo.Close()
|
||||
ctx.Repo.GitRepo = nil
|
||||
}
|
||||
@@ -616,7 +600,6 @@ func RepoAssignment(ctx *Context) {
|
||||
if strings.Contains(err.Error(), "repository does not exist") || strings.Contains(err.Error(), "no such file or directory") {
|
||||
log.Error("Repository %-v has a broken repository on the file system: %s Error: %v", ctx.Repo.Repository, ctx.Repo.Repository.RepoPath(), err)
|
||||
ctx.Repo.Repository.MarkAsBrokenEmpty()
|
||||
ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch
|
||||
// Only allow access to base of repo or settings
|
||||
if !isHomeOrSettings {
|
||||
ctx.Redirect(ctx.Repo.RepoLink)
|
||||
@@ -629,7 +612,6 @@ func RepoAssignment(ctx *Context) {
|
||||
|
||||
// Stop at this point when the repo is empty.
|
||||
if ctx.Repo.Repository.IsEmpty {
|
||||
ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch
|
||||
return
|
||||
}
|
||||
|
||||
@@ -655,22 +637,6 @@ func RepoAssignment(ctx *Context) {
|
||||
|
||||
ctx.Data["BranchesCount"] = branchesTotal
|
||||
|
||||
// If no branch is set in the request URL, try to guess a default one.
|
||||
if len(ctx.Repo.BranchName) == 0 {
|
||||
if len(ctx.Repo.Repository.DefaultBranch) > 0 && ctx.Repo.GitRepo.IsBranchExist(ctx.Repo.Repository.DefaultBranch) {
|
||||
ctx.Repo.BranchName = ctx.Repo.Repository.DefaultBranch
|
||||
} else {
|
||||
ctx.Repo.BranchName, _ = gitrepo.GetDefaultBranch(ctx, ctx.Repo.Repository)
|
||||
if ctx.Repo.BranchName == "" {
|
||||
// If it still can't get a default branch, fall back to default branch from setting.
|
||||
// Something might be wrong. Either site admin should fix the repo sync or Gitea should fix a potential bug.
|
||||
ctx.Repo.BranchName = setting.Repository.DefaultBranch
|
||||
}
|
||||
}
|
||||
ctx.Repo.RefName = ctx.Repo.BranchName
|
||||
}
|
||||
ctx.Data["BranchName"] = ctx.Repo.BranchName
|
||||
|
||||
// People who have push access or have forked repository can propose a new pull request.
|
||||
canPush := ctx.Repo.CanWrite(unit_model.TypeCode) ||
|
||||
(ctx.IsSigned && repo_model.HasForkedRepo(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID))
|
||||
@@ -713,7 +679,7 @@ func RepoAssignment(ctx *Context) {
|
||||
}
|
||||
|
||||
if ctx.FormString("go-get") == "1" {
|
||||
ctx.Data["GoGetImport"] = ComposeGoGetImport(ctx, owner.Name, repo.Name)
|
||||
ctx.Data["GoGetImport"] = ComposeGoGetImport(ctx, repo.Owner.Name, repo.Name)
|
||||
fullURLPrefix := repo.HTMLURL() + "/src/branch/" + util.PathEscapeSegments(ctx.Repo.BranchName)
|
||||
ctx.Data["GoDocDirectory"] = fullURLPrefix + "{/dir}"
|
||||
ctx.Data["GoDocFile"] = fullURLPrefix + "{/dir}/{file}#L{line}"
|
||||
@@ -844,26 +810,39 @@ type RepoRefByTypeOptions struct {
|
||||
IgnoreNotExistErr bool
|
||||
}
|
||||
|
||||
func repoRefFullName(shortName string, typ RepoRefType) git.RefName {
|
||||
switch typ {
|
||||
case RepoRefBranch:
|
||||
return git.RefNameFromBranch(shortName)
|
||||
case RepoRefTag:
|
||||
return git.RefNameFromTag(shortName)
|
||||
case RepoRefCommit:
|
||||
return git.RefNameFromCommit(shortName)
|
||||
default:
|
||||
setting.PanicInDevOrTesting("Unknown RepoRefType: %v", typ)
|
||||
return git.RefNameFromBranch("main") // just a dummy result, it shouldn't happen
|
||||
}
|
||||
}
|
||||
|
||||
// RepoRefByType handles repository reference name for a specific type
|
||||
// of repository reference
|
||||
func RepoRefByType(detectRefType RepoRefType, opts ...RepoRefByTypeOptions) func(*Context) {
|
||||
opt := util.OptionalArg(opts)
|
||||
return func(ctx *Context) {
|
||||
var err error
|
||||
refType := detectRefType
|
||||
// Empty repository does not have reference information.
|
||||
if ctx.Repo.Repository.IsEmpty {
|
||||
// assume the user is viewing the (non-existent) default branch
|
||||
ctx.Repo.IsViewBranch = true
|
||||
ctx.Repo.BranchName = ctx.Repo.Repository.DefaultBranch
|
||||
ctx.Repo.RefFullName = git.RefNameFromBranch(ctx.Repo.BranchName)
|
||||
// these variables are used by the template to "add/upload" new files
|
||||
ctx.Data["BranchName"] = ctx.Repo.BranchName
|
||||
ctx.Data["TreePath"] = ""
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
refName string
|
||||
err error
|
||||
)
|
||||
|
||||
if ctx.Repo.GitRepo == nil {
|
||||
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository)
|
||||
if err != nil {
|
||||
@@ -873,22 +852,23 @@ func RepoRefByType(detectRefType RepoRefType, opts ...RepoRefByTypeOptions) func
|
||||
}
|
||||
|
||||
// Get default branch.
|
||||
var refShortName string
|
||||
reqPath := ctx.PathParam("*")
|
||||
if reqPath == "" {
|
||||
refName = ctx.Repo.Repository.DefaultBranch
|
||||
if !ctx.Repo.GitRepo.IsBranchExist(refName) {
|
||||
refShortName = ctx.Repo.Repository.DefaultBranch
|
||||
if !ctx.Repo.GitRepo.IsBranchExist(refShortName) {
|
||||
brs, _, err := ctx.Repo.GitRepo.GetBranches(0, 1)
|
||||
if err == nil && len(brs) != 0 {
|
||||
refName = brs[0].Name
|
||||
refShortName = brs[0].Name
|
||||
} else if len(brs) == 0 {
|
||||
log.Error("No branches in non-empty repository %s", ctx.Repo.GitRepo.Path)
|
||||
} else {
|
||||
log.Error("GetBranches error: %v", err)
|
||||
}
|
||||
}
|
||||
ctx.Repo.RefName = refName
|
||||
ctx.Repo.BranchName = refName
|
||||
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName)
|
||||
ctx.Repo.RefFullName = git.RefNameFromBranch(refShortName)
|
||||
ctx.Repo.BranchName = refShortName
|
||||
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refShortName)
|
||||
if err == nil {
|
||||
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
|
||||
} else if strings.Contains(err.Error(), "fatal: not a git repository") || strings.Contains(err.Error(), "object does not exist") {
|
||||
@@ -902,35 +882,37 @@ func RepoRefByType(detectRefType RepoRefType, opts ...RepoRefByTypeOptions) func
|
||||
} else { // there is a path in request
|
||||
guessLegacyPath := refType == RepoRefUnknown
|
||||
if guessLegacyPath {
|
||||
refName, refType = getRefNameLegacy(ctx.Base, ctx.Repo, reqPath, "")
|
||||
refShortName, refType = getRefNameLegacy(ctx.Base, ctx.Repo, reqPath, "")
|
||||
} else {
|
||||
refName = getRefName(ctx.Base, ctx.Repo, reqPath, refType)
|
||||
refShortName = getRefName(ctx.Base, ctx.Repo, reqPath, refType)
|
||||
}
|
||||
ctx.Repo.RefName = refName
|
||||
ctx.Repo.RefFullName = repoRefFullName(refShortName, refType)
|
||||
isRenamedBranch, has := ctx.Data["IsRenamedBranch"].(bool)
|
||||
if isRenamedBranch && has {
|
||||
renamedBranchName := ctx.Data["RenamedBranchName"].(string)
|
||||
ctx.Flash.Info(ctx.Tr("repo.branch.renamed", refName, renamedBranchName))
|
||||
link := setting.AppSubURL + strings.Replace(ctx.Req.URL.EscapedPath(), util.PathEscapeSegments(refName), util.PathEscapeSegments(renamedBranchName), 1)
|
||||
ctx.Flash.Info(ctx.Tr("repo.branch.renamed", refShortName, renamedBranchName))
|
||||
link := setting.AppSubURL + strings.Replace(ctx.Req.URL.EscapedPath(), util.PathEscapeSegments(refShortName), util.PathEscapeSegments(renamedBranchName), 1)
|
||||
ctx.Redirect(link)
|
||||
return
|
||||
}
|
||||
|
||||
if refType == RepoRefBranch && ctx.Repo.GitRepo.IsBranchExist(refName) {
|
||||
if refType == RepoRefBranch && ctx.Repo.GitRepo.IsBranchExist(refShortName) {
|
||||
ctx.Repo.IsViewBranch = true
|
||||
ctx.Repo.BranchName = refName
|
||||
ctx.Repo.BranchName = refShortName
|
||||
ctx.Repo.RefFullName = git.RefNameFromBranch(refShortName)
|
||||
|
||||
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName)
|
||||
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refShortName)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetBranchCommit", err)
|
||||
return
|
||||
}
|
||||
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
|
||||
} else if refType == RepoRefTag && ctx.Repo.GitRepo.IsTagExist(refName) {
|
||||
} else if refType == RepoRefTag && ctx.Repo.GitRepo.IsTagExist(refShortName) {
|
||||
ctx.Repo.IsViewTag = true
|
||||
ctx.Repo.TagName = refName
|
||||
ctx.Repo.RefFullName = git.RefNameFromTag(refShortName)
|
||||
ctx.Repo.TagName = refShortName
|
||||
|
||||
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetTagCommit(refName)
|
||||
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetTagCommit(refShortName)
|
||||
if err != nil {
|
||||
if git.IsErrNotExist(err) {
|
||||
ctx.NotFound("GetTagCommit", err)
|
||||
@@ -940,25 +922,26 @@ func RepoRefByType(detectRefType RepoRefType, opts ...RepoRefByTypeOptions) func
|
||||
return
|
||||
}
|
||||
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
|
||||
} else if git.IsStringLikelyCommitID(ctx.Repo.GetObjectFormat(), refName, 7) {
|
||||
} else if git.IsStringLikelyCommitID(ctx.Repo.GetObjectFormat(), refShortName, 7) {
|
||||
ctx.Repo.IsViewCommit = true
|
||||
ctx.Repo.CommitID = refName
|
||||
ctx.Repo.RefFullName = git.RefNameFromCommit(refShortName)
|
||||
ctx.Repo.CommitID = refShortName
|
||||
|
||||
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetCommit(refName)
|
||||
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetCommit(refShortName)
|
||||
if err != nil {
|
||||
ctx.NotFound("GetCommit", err)
|
||||
return
|
||||
}
|
||||
// If short commit ID add canonical link header
|
||||
if len(refName) < ctx.Repo.GetObjectFormat().FullLength() {
|
||||
canonicalURL := util.URLJoin(httplib.GuessCurrentAppURL(ctx), strings.Replace(ctx.Req.URL.RequestURI(), util.PathEscapeSegments(refName), url.PathEscape(ctx.Repo.Commit.ID.String()), 1))
|
||||
if len(refShortName) < ctx.Repo.GetObjectFormat().FullLength() {
|
||||
canonicalURL := util.URLJoin(httplib.GuessCurrentAppURL(ctx), strings.Replace(ctx.Req.URL.RequestURI(), util.PathEscapeSegments(refShortName), url.PathEscape(ctx.Repo.Commit.ID.String()), 1))
|
||||
ctx.RespHeader().Set("Link", fmt.Sprintf(`<%s>; rel="canonical"`, canonicalURL))
|
||||
}
|
||||
} else {
|
||||
if opt.IgnoreNotExistErr {
|
||||
return
|
||||
}
|
||||
ctx.NotFound("RepoRef invalid repo", fmt.Errorf("branch or tag not exist: %s", refName))
|
||||
ctx.NotFound("RepoRef invalid repo", fmt.Errorf("branch or tag not exist: %s", refShortName))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -975,15 +958,19 @@ func RepoRefByType(detectRefType RepoRefType, opts ...RepoRefByTypeOptions) func
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Data["BranchName"] = ctx.Repo.BranchName
|
||||
ctx.Data["RefName"] = ctx.Repo.RefName
|
||||
ctx.Data["RefFullName"] = ctx.Repo.RefFullName
|
||||
ctx.Data["RefTypeNameSubURL"] = ctx.Repo.RefTypeNameSubURL()
|
||||
ctx.Data["TagName"] = ctx.Repo.TagName
|
||||
ctx.Data["CommitID"] = ctx.Repo.CommitID
|
||||
ctx.Data["TreePath"] = ctx.Repo.TreePath
|
||||
|
||||
ctx.Data["IsViewBranch"] = ctx.Repo.IsViewBranch
|
||||
ctx.Data["BranchName"] = ctx.Repo.BranchName
|
||||
|
||||
ctx.Data["IsViewTag"] = ctx.Repo.IsViewTag
|
||||
ctx.Data["TagName"] = ctx.Repo.TagName
|
||||
|
||||
ctx.Data["IsViewCommit"] = ctx.Repo.IsViewCommit
|
||||
ctx.Data["CommitID"] = ctx.Repo.CommitID
|
||||
|
||||
ctx.Data["CanCreateBranch"] = ctx.Repo.CanCreateBranch() // only used by the branch selector dropdown: AllowCreateNewRef
|
||||
|
||||
ctx.Repo.CommitsCount, err = ctx.Repo.GetCommitsCount()
|
||||
|
@@ -31,19 +31,20 @@ import (
|
||||
// handle elsewhere.
|
||||
type ArchiveRequest struct {
|
||||
RepoID int64
|
||||
refName string
|
||||
Type git.ArchiveType
|
||||
CommitID string
|
||||
|
||||
archiveRefShortName string // the ref short name to download the archive, for example: "master", "v1.0.0", "commit id"
|
||||
}
|
||||
|
||||
// ErrUnknownArchiveFormat request archive format is not supported
|
||||
type ErrUnknownArchiveFormat struct {
|
||||
RequestFormat string
|
||||
RequestNameType string
|
||||
}
|
||||
|
||||
// Error implements error
|
||||
func (err ErrUnknownArchiveFormat) Error() string {
|
||||
return fmt.Sprintf("unknown format: %s", err.RequestFormat)
|
||||
return fmt.Sprintf("unknown format: %s", err.RequestNameType)
|
||||
}
|
||||
|
||||
// Is implements error
|
||||
@@ -54,12 +55,12 @@ func (ErrUnknownArchiveFormat) Is(err error) bool {
|
||||
|
||||
// RepoRefNotFoundError is returned when a requested reference (commit, tag) was not found.
|
||||
type RepoRefNotFoundError struct {
|
||||
RefName string
|
||||
RefShortName string
|
||||
}
|
||||
|
||||
// Error implements error.
|
||||
func (e RepoRefNotFoundError) Error() string {
|
||||
return fmt.Sprintf("unrecognized repository reference: %s", e.RefName)
|
||||
return fmt.Sprintf("unrecognized repository reference: %s", e.RefShortName)
|
||||
}
|
||||
|
||||
func (e RepoRefNotFoundError) Is(err error) bool {
|
||||
@@ -67,43 +68,23 @@ func (e RepoRefNotFoundError) Is(err error) bool {
|
||||
return ok
|
||||
}
|
||||
|
||||
func ParseFileName(uri string) (ext string, tp git.ArchiveType, err error) {
|
||||
switch {
|
||||
case strings.HasSuffix(uri, ".zip"):
|
||||
ext = ".zip"
|
||||
tp = git.ZIP
|
||||
case strings.HasSuffix(uri, ".tar.gz"):
|
||||
ext = ".tar.gz"
|
||||
tp = git.TARGZ
|
||||
case strings.HasSuffix(uri, ".bundle"):
|
||||
ext = ".bundle"
|
||||
tp = git.BUNDLE
|
||||
default:
|
||||
return "", 0, ErrUnknownArchiveFormat{RequestFormat: uri}
|
||||
}
|
||||
return ext, tp, nil
|
||||
}
|
||||
|
||||
// NewRequest creates an archival request, based on the URI. The
|
||||
// resulting ArchiveRequest is suitable for being passed to Await()
|
||||
// if it's determined that the request still needs to be satisfied.
|
||||
func NewRequest(repoID int64, repo *git.Repository, refName string, fileType git.ArchiveType) (*ArchiveRequest, error) {
|
||||
if fileType < git.ZIP || fileType > git.BUNDLE {
|
||||
return nil, ErrUnknownArchiveFormat{RequestFormat: fileType.String()}
|
||||
}
|
||||
|
||||
r := &ArchiveRequest{
|
||||
RepoID: repoID,
|
||||
refName: refName,
|
||||
Type: fileType,
|
||||
func NewRequest(repoID int64, repo *git.Repository, archiveRefExt string) (*ArchiveRequest, error) {
|
||||
// here the archiveRefShortName is not a clear ref, it could be a tag, branch or commit id
|
||||
archiveRefShortName, archiveType := git.SplitArchiveNameType(archiveRefExt)
|
||||
if archiveType == git.ArchiveUnknown {
|
||||
return nil, ErrUnknownArchiveFormat{archiveRefExt}
|
||||
}
|
||||
|
||||
// Get corresponding commit.
|
||||
commitID, err := repo.ConvertToGitID(r.refName)
|
||||
commitID, err := repo.ConvertToGitID(archiveRefShortName)
|
||||
if err != nil {
|
||||
return nil, RepoRefNotFoundError{RefName: r.refName}
|
||||
return nil, RepoRefNotFoundError{RefShortName: archiveRefShortName}
|
||||
}
|
||||
|
||||
r := &ArchiveRequest{RepoID: repoID, archiveRefShortName: archiveRefShortName, Type: archiveType}
|
||||
r.CommitID = commitID.String()
|
||||
return r, nil
|
||||
}
|
||||
@@ -111,11 +92,11 @@ func NewRequest(repoID int64, repo *git.Repository, refName string, fileType git
|
||||
// GetArchiveName returns the name of the caller, based on the ref used by the
|
||||
// caller to create this request.
|
||||
func (aReq *ArchiveRequest) GetArchiveName() string {
|
||||
return strings.ReplaceAll(aReq.refName, "/", "-") + "." + aReq.Type.String()
|
||||
return strings.ReplaceAll(aReq.archiveRefShortName, "/", "-") + "." + aReq.Type.String()
|
||||
}
|
||||
|
||||
// Await awaits the completion of an ArchiveRequest. If the archive has
|
||||
// already been prepared the method returns immediately. Otherwise an archiver
|
||||
// already been prepared the method returns immediately. Otherwise, an archiver
|
||||
// process will be started and its completion awaited. On success the returned
|
||||
// RepoArchiver may be used to download the archive. Note that even if the
|
||||
// context is cancelled/times out a started archiver will still continue to run
|
||||
@@ -208,8 +189,8 @@ func doArchive(ctx context.Context, r *ArchiveRequest) (*repo_model.RepoArchiver
|
||||
|
||||
rd, w := io.Pipe()
|
||||
defer func() {
|
||||
w.Close()
|
||||
rd.Close()
|
||||
_ = w.Close()
|
||||
_ = rd.Close()
|
||||
}()
|
||||
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)
|
||||
@@ -230,7 +211,7 @@ func doArchive(ctx context.Context, r *ArchiveRequest) (*repo_model.RepoArchiver
|
||||
}
|
||||
}()
|
||||
|
||||
if archiver.Type == git.BUNDLE {
|
||||
if archiver.Type == git.ArchiveBundle {
|
||||
err = gitRepo.CreateBundle(
|
||||
ctx,
|
||||
archiver.CommitID,
|
||||
|
@@ -9,7 +9,6 @@ import (
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/services/contexttest"
|
||||
|
||||
_ "code.gitea.io/gitea/models/actions"
|
||||
@@ -31,47 +30,47 @@ func TestArchive_Basic(t *testing.T) {
|
||||
contexttest.LoadGitRepo(t, ctx)
|
||||
defer ctx.Repo.GitRepo.Close()
|
||||
|
||||
bogusReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit, git.ZIP)
|
||||
bogusReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".zip")
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, bogusReq)
|
||||
assert.EqualValues(t, firstCommit+".zip", bogusReq.GetArchiveName())
|
||||
|
||||
// Check a series of bogus requests.
|
||||
// Step 1, valid commit with a bad extension.
|
||||
bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit, 100)
|
||||
bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".unknown")
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, bogusReq)
|
||||
|
||||
// Step 2, missing commit.
|
||||
bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "dbffff", git.ZIP)
|
||||
bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "dbffff.zip")
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, bogusReq)
|
||||
|
||||
// Step 3, doesn't look like branch/tag/commit.
|
||||
bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "db", git.ZIP)
|
||||
bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "db.zip")
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, bogusReq)
|
||||
|
||||
bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "master", git.ZIP)
|
||||
bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "master.zip")
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, bogusReq)
|
||||
assert.EqualValues(t, "master.zip", bogusReq.GetArchiveName())
|
||||
|
||||
bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "test/archive", git.ZIP)
|
||||
bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "test/archive.zip")
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, bogusReq)
|
||||
assert.EqualValues(t, "test-archive.zip", bogusReq.GetArchiveName())
|
||||
|
||||
// Now two valid requests, firstCommit with valid extensions.
|
||||
zipReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit, git.ZIP)
|
||||
zipReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".zip")
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, zipReq)
|
||||
|
||||
tgzReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit, git.TARGZ)
|
||||
tgzReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".tar.gz")
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, tgzReq)
|
||||
|
||||
secondReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, secondCommit, git.ZIP)
|
||||
secondReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, secondCommit+".bundle")
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, secondReq)
|
||||
|
||||
@@ -91,7 +90,7 @@ func TestArchive_Basic(t *testing.T) {
|
||||
// Sleep two seconds to make sure the queue doesn't change.
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
zipReq2, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit, git.ZIP)
|
||||
zipReq2, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".zip")
|
||||
assert.NoError(t, err)
|
||||
// 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
|
||||
@@ -106,12 +105,12 @@ func TestArchive_Basic(t *testing.T) {
|
||||
// Now we'll submit a request and TimedWaitForCompletion twice, before and
|
||||
// after we release it. We should trigger both the timeout and non-timeout
|
||||
// cases.
|
||||
timedReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, secondCommit, git.TARGZ)
|
||||
timedReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, secondCommit+".tar.gz")
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, timedReq)
|
||||
doArchive(db.DefaultContext, timedReq)
|
||||
|
||||
zipReq2, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit, git.ZIP)
|
||||
zipReq2, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".zip")
|
||||
assert.NoError(t, err)
|
||||
// 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
|
||||
@@ -129,6 +128,6 @@ func TestArchive_Basic(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestErrUnknownArchiveFormat(t *testing.T) {
|
||||
err := ErrUnknownArchiveFormat{RequestFormat: "master"}
|
||||
err := ErrUnknownArchiveFormat{RequestNameType: "xxx"}
|
||||
assert.ErrorIs(t, err, ErrUnknownArchiveFormat{})
|
||||
}
|
||||
|
Reference in New Issue
Block a user