Skip to content

Commit 53e9c63

Browse files
authored
Merge branch 'main' into patch-17
2 parents 50a4ceb + 703be6b commit 53e9c63

File tree

14 files changed

+201
-54
lines changed

14 files changed

+201
-54
lines changed

models/activities/action.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -770,15 +770,15 @@ func DeleteIssueActions(ctx context.Context, repoID, issueID, issueIndex int64)
770770
// CountActionCreatedUnixString count actions where created_unix is an empty string
771771
func CountActionCreatedUnixString(ctx context.Context) (int64, error) {
772772
if setting.Database.Type.IsSQLite3() {
773-
return db.GetEngine(ctx).Where(`created_unix = ""`).Count(new(Action))
773+
return db.GetEngine(ctx).Where(`created_unix = ''`).Count(new(Action))
774774
}
775775
return 0, nil
776776
}
777777

778778
// FixActionCreatedUnixString set created_unix to zero if it is an empty string
779779
func FixActionCreatedUnixString(ctx context.Context) (int64, error) {
780780
if setting.Database.Type.IsSQLite3() {
781-
res, err := db.GetEngine(ctx).Exec(`UPDATE action SET created_unix = 0 WHERE created_unix = ""`)
781+
res, err := db.GetEngine(ctx).Exec(`UPDATE action SET created_unix = 0 WHERE created_unix = ''`)
782782
if err != nil {
783783
return 0, err
784784
}

models/activities/action_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ func TestConsistencyUpdateAction(t *testing.T) {
256256
unittest.AssertExistsAndLoadBean(t, &activities_model.Action{
257257
ID: int64(id),
258258
})
259-
_, err := db.GetEngine(db.DefaultContext).Exec(`UPDATE action SET created_unix = "" WHERE id = ?`, id)
259+
_, err := db.GetEngine(db.DefaultContext).Exec(`UPDATE action SET created_unix = '' WHERE id = ?`, id)
260260
assert.NoError(t, err)
261261
actions := make([]*activities_model.Action, 0, 1)
262262
//

models/issues/label_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ func TestDeleteIssueLabel(t *testing.T) {
406406
PosterID: doerID,
407407
IssueID: issueID,
408408
LabelID: labelID,
409-
}, `content=""`)
409+
}, `content=''`)
410410
label = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID})
411411
assert.EqualValues(t, expectedNumIssues, label.NumIssues)
412412
assert.EqualValues(t, expectedNumClosedIssues, label.NumClosedIssues)

modules/indexer/code/indexer_test.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ import (
2222

2323
"github.com/stretchr/testify/assert"
2424
"github.com/stretchr/testify/require"
25-
26-
_ "github.com/mattn/go-sqlite3"
2725
)
2826

2927
type codeSearchResult struct {

routers/api/v1/api.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,6 +1377,8 @@ func Routes() *web.Router {
13771377
m.Post("", bind(api.UpdateRepoAvatarOption{}), repo.UpdateAvatar)
13781378
m.Delete("", repo.DeleteAvatar)
13791379
}, reqAdmin(), reqToken())
1380+
1381+
m.Get("/{ball_type:tarball|zipball|bundle}/*", reqRepoReader(unit.TypeCode), repo.DownloadArchive)
13801382
}, repoAssignment(), checkTokenPublicOnly())
13811383
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryRepository))
13821384

routers/api/v1/misc/markup_test.go

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,37 @@ import (
77
go_context "context"
88
"io"
99
"net/http"
10+
"os"
1011
"path"
1112
"strings"
1213
"testing"
1314

15+
repo_model "code.gitea.io/gitea/models/repo"
16+
"code.gitea.io/gitea/models/unittest"
1417
"code.gitea.io/gitea/modules/markup"
1518
"code.gitea.io/gitea/modules/setting"
1619
api "code.gitea.io/gitea/modules/structs"
1720
"code.gitea.io/gitea/modules/test"
1821
"code.gitea.io/gitea/modules/web"
22+
context_service "code.gitea.io/gitea/services/context"
1923
"code.gitea.io/gitea/services/contexttest"
2024

2125
"github.com/stretchr/testify/assert"
2226
)
2327

2428
const AppURL = "http://localhost:3000/"
2529

30+
func TestMain(m *testing.M) {
31+
unittest.MainTest(m, &unittest.TestOptions{
32+
FixtureFiles: []string{"repository.yml", "user.yml"},
33+
})
34+
os.Exit(m.Run())
35+
}
36+
2637
func testRenderMarkup(t *testing.T, mode string, wiki bool, filePath, text, expectedBody string, expectedCode int) {
2738
setting.AppURL = AppURL
2839
defer test.MockVariableValue(&markup.RenderBehaviorForTesting.DisableAdditionalAttributes, true)()
29-
context := "/gogits/gogs"
40+
context := "/user2/repo1"
3041
if !wiki {
3142
context += path.Join("/src/branch/main", path.Dir(filePath))
3243
}
@@ -38,6 +49,8 @@ func testRenderMarkup(t *testing.T, mode string, wiki bool, filePath, text, expe
3849
FilePath: filePath,
3950
}
4051
ctx, resp := contexttest.MockAPIContext(t, "POST /api/v1/markup")
52+
ctx.Repo = &context_service.Repository{}
53+
ctx.Repo.Repository = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
4154
web.SetForm(ctx, &options)
4255
Markup(ctx)
4356
assert.Equal(t, expectedBody, resp.Body.String())
@@ -48,7 +61,7 @@ func testRenderMarkup(t *testing.T, mode string, wiki bool, filePath, text, expe
4861
func testRenderMarkdown(t *testing.T, mode string, wiki bool, text, responseBody string, responseCode int) {
4962
defer test.MockVariableValue(&markup.RenderBehaviorForTesting.DisableAdditionalAttributes, true)()
5063
setting.AppURL = AppURL
51-
context := "/gogits/gogs"
64+
context := "/user2/repo1"
5265
if !wiki {
5366
context += "/src/branch/main"
5467
}
@@ -67,6 +80,7 @@ func testRenderMarkdown(t *testing.T, mode string, wiki bool, text, responseBody
6780
}
6881

6982
func TestAPI_RenderGFM(t *testing.T) {
83+
unittest.PrepareTestEnv(t)
7084
markup.Init(&markup.RenderHelperFuncs{
7185
IsUsernameMentionable: func(ctx go_context.Context, username string) bool {
7286
return username == "r-lyeh"
@@ -82,20 +96,20 @@ func TestAPI_RenderGFM(t *testing.T) {
8296
// rendered
8397
`<p>Wiki! Enjoy :)</p>
8498
<ul>
85-
<li><a href="http://localhost:3000/gogits/gogs/wiki/Links" rel="nofollow">Links, Language bindings, Engine bindings</a></li>
86-
<li><a href="http://localhost:3000/gogits/gogs/wiki/Tips" rel="nofollow">Tips</a></li>
99+
<li><a href="http://localhost:3000/user2/repo1/wiki/Links" rel="nofollow">Links, Language bindings, Engine bindings</a></li>
100+
<li><a href="http://localhost:3000/user2/repo1/wiki/Tips" rel="nofollow">Tips</a></li>
87101
<li>Bezier widget (by <a href="http://localhost:3000/r-lyeh" rel="nofollow">@r-lyeh</a>) <a href="https://github.com/ocornut/imgui/issues/786" rel="nofollow">https://github.com/ocornut/imgui/issues/786</a></li>
88102
</ul>
89103
`,
90104
// Guard wiki sidebar: special syntax
91105
`[[Guardfile-DSL / Configuring-Guard|Guardfile-DSL---Configuring-Guard]]`,
92106
// rendered
93-
`<p><a href="http://localhost:3000/gogits/gogs/wiki/Guardfile-DSL---Configuring-Guard" rel="nofollow">Guardfile-DSL / Configuring-Guard</a></p>
107+
`<p><a href="http://localhost:3000/user2/repo1/wiki/Guardfile-DSL---Configuring-Guard" rel="nofollow">Guardfile-DSL / Configuring-Guard</a></p>
94108
`,
95109
// special syntax
96110
`[[Name|Link]]`,
97111
// rendered
98-
`<p><a href="http://localhost:3000/gogits/gogs/wiki/Link" rel="nofollow">Name</a></p>
112+
`<p><a href="http://localhost:3000/user2/repo1/wiki/Link" rel="nofollow">Name</a></p>
99113
`,
100114
// empty
101115
``,
@@ -119,8 +133,8 @@ Here are some links to the most important topics. You can find the full list of
119133
<p><strong>Wine Staging</strong> on website <a href="http://wine-staging.com" rel="nofollow">wine-staging.com</a>.</p>
120134
<h2 id="user-content-quick-links">Quick Links</h2>
121135
<p>Here are some links to the most important topics. You can find the full list of pages at the sidebar.</p>
122-
<p><a href="http://localhost:3000/gogits/gogs/wiki/Configuration" rel="nofollow">Configuration</a>
123-
<a href="http://localhost:3000/gogits/gogs/wiki/raw/images/icon-bug.png" rel="nofollow"><img src="http://localhost:3000/gogits/gogs/wiki/raw/images/icon-bug.png" title="icon-bug.png" alt="images/icon-bug.png"/></a></p>
136+
<p><a href="http://localhost:3000/user2/repo1/wiki/Configuration" rel="nofollow">Configuration</a>
137+
<a href="http://localhost:3000/user2/repo1/wiki/raw/images/icon-bug.png" rel="nofollow"><img src="http://localhost:3000/user2/repo1/wiki/raw/images/icon-bug.png" title="icon-bug.png" alt="images/icon-bug.png"/></a></p>
124138
`,
125139
}
126140

@@ -143,20 +157,20 @@ Here are some links to the most important topics. You can find the full list of
143157
}
144158

145159
input := "[Link](test.md)\n![Image](image.png)"
146-
testRenderMarkdown(t, "gfm", false, input, `<p><a href="http://localhost:3000/gogits/gogs/src/branch/main/test.md" rel="nofollow">Link</a>
147-
<a href="http://localhost:3000/gogits/gogs/media/branch/main/image.png" target="_blank" rel="nofollow noopener"><img src="http://localhost:3000/gogits/gogs/media/branch/main/image.png" alt="Image"/></a></p>
160+
testRenderMarkdown(t, "gfm", false, input, `<p><a href="http://localhost:3000/user2/repo1/src/branch/main/test.md" rel="nofollow">Link</a>
161+
<a href="http://localhost:3000/user2/repo1/media/branch/main/image.png" target="_blank" rel="nofollow noopener"><img src="http://localhost:3000/user2/repo1/media/branch/main/image.png" alt="Image"/></a></p>
148162
`, http.StatusOK)
149163

150-
testRenderMarkdown(t, "gfm", false, input, `<p><a href="http://localhost:3000/gogits/gogs/src/branch/main/test.md" rel="nofollow">Link</a>
151-
<a href="http://localhost:3000/gogits/gogs/media/branch/main/image.png" target="_blank" rel="nofollow noopener"><img src="http://localhost:3000/gogits/gogs/media/branch/main/image.png" alt="Image"/></a></p>
164+
testRenderMarkdown(t, "gfm", false, input, `<p><a href="http://localhost:3000/user2/repo1/src/branch/main/test.md" rel="nofollow">Link</a>
165+
<a href="http://localhost:3000/user2/repo1/media/branch/main/image.png" target="_blank" rel="nofollow noopener"><img src="http://localhost:3000/user2/repo1/media/branch/main/image.png" alt="Image"/></a></p>
152166
`, http.StatusOK)
153167

154-
testRenderMarkup(t, "gfm", false, "", input, `<p><a href="http://localhost:3000/gogits/gogs/src/branch/main/test.md" rel="nofollow">Link</a>
155-
<a href="http://localhost:3000/gogits/gogs/media/branch/main/image.png" target="_blank" rel="nofollow noopener"><img src="http://localhost:3000/gogits/gogs/media/branch/main/image.png" alt="Image"/></a></p>
168+
testRenderMarkup(t, "gfm", false, "", input, `<p><a href="http://localhost:3000/user2/repo1/src/branch/main/test.md" rel="nofollow">Link</a>
169+
<a href="http://localhost:3000/user2/repo1/media/branch/main/image.png" target="_blank" rel="nofollow noopener"><img src="http://localhost:3000/user2/repo1/media/branch/main/image.png" alt="Image"/></a></p>
156170
`, http.StatusOK)
157171

158-
testRenderMarkup(t, "file", false, "path/new-file.md", input, `<p><a href="http://localhost:3000/gogits/gogs/src/branch/main/path/test.md" rel="nofollow">Link</a>
159-
<a href="http://localhost:3000/gogits/gogs/media/branch/main/path/image.png" target="_blank" rel="nofollow noopener"><img src="http://localhost:3000/gogits/gogs/media/branch/main/path/image.png" alt="Image"/></a></p>
172+
testRenderMarkup(t, "file", false, "path/new-file.md", input, `<p><a href="http://localhost:3000/user2/repo1/src/branch/main/path/test.md" rel="nofollow">Link</a>
173+
<a href="http://localhost:3000/user2/repo1/media/branch/main/path/image.png" target="_blank" rel="nofollow noopener"><img src="http://localhost:3000/user2/repo1/media/branch/main/path/image.png" alt="Image"/></a></p>
160174
`, http.StatusOK)
161175

162176
testRenderMarkup(t, "file", false, "path/test.unknown", "## Test", "unsupported file to render: \"path/test.unknown\"\n", http.StatusUnprocessableEntity)
@@ -186,7 +200,7 @@ func TestAPI_RenderSimple(t *testing.T) {
186200
options := api.MarkdownOption{
187201
Mode: "markdown",
188202
Text: "",
189-
Context: "/gogits/gogs",
203+
Context: "/user2/repo1",
190204
}
191205
ctx, resp := contexttest.MockAPIContext(t, "POST /api/v1/markdown")
192206
for i := 0; i < len(simpleCases); i += 2 {

routers/api/v1/repo/download.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright 2024 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package repo
5+
6+
import (
7+
"fmt"
8+
"net/http"
9+
10+
"code.gitea.io/gitea/modules/git"
11+
"code.gitea.io/gitea/modules/gitrepo"
12+
"code.gitea.io/gitea/services/context"
13+
archiver_service "code.gitea.io/gitea/services/repository/archiver"
14+
)
15+
16+
func DownloadArchive(ctx *context.APIContext) {
17+
var tp git.ArchiveType
18+
switch ballType := ctx.PathParam("ball_type"); ballType {
19+
case "tarball":
20+
tp = git.TARGZ
21+
case "zipball":
22+
tp = git.ZIP
23+
case "bundle":
24+
tp = git.BUNDLE
25+
default:
26+
ctx.Error(http.StatusBadRequest, "", fmt.Sprintf("Unknown archive type: %s", ballType))
27+
return
28+
}
29+
30+
if ctx.Repo.GitRepo == nil {
31+
gitRepo, err := gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
32+
if err != nil {
33+
ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
34+
return
35+
}
36+
ctx.Repo.GitRepo = gitRepo
37+
defer gitRepo.Close()
38+
}
39+
40+
r, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.PathParam("*"), tp)
41+
if err != nil {
42+
ctx.ServerError("NewRequest", err)
43+
return
44+
}
45+
46+
archive, err := r.Await(ctx)
47+
if err != nil {
48+
ctx.ServerError("archive.Await", err)
49+
return
50+
}
51+
52+
download(ctx, r.GetArchiveName(), archive)
53+
}

routers/api/v1/repo/file.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,13 @@ func GetArchive(ctx *context.APIContext) {
301301

302302
func archiveDownload(ctx *context.APIContext) {
303303
uri := ctx.PathParam("*")
304-
aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, uri)
304+
ext, tp, err := archiver_service.ParseFileName(uri)
305+
if err != nil {
306+
ctx.Error(http.StatusBadRequest, "ParseFileName", err)
307+
return
308+
}
309+
310+
aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, strings.TrimSuffix(uri, ext), tp)
305311
if err != nil {
306312
if errors.Is(err, archiver_service.ErrUnknownArchiveFormat{}) {
307313
ctx.Error(http.StatusBadRequest, "unknown archive format", err)
@@ -327,9 +333,12 @@ func download(ctx *context.APIContext, archiveName string, archiver *repo_model.
327333

328334
// Add nix format link header so tarballs lock correctly:
329335
// https://github.com/nixos/nix/blob/56763ff918eb308db23080e560ed2ea3e00c80a7/doc/manual/src/protocols/tarball-fetcher.md
330-
ctx.Resp.Header().Add("Link", fmt.Sprintf(`<%s/archive/%s.tar.gz?rev=%s>; rel="immutable"`,
336+
ctx.Resp.Header().Add("Link", fmt.Sprintf(`<%s/archive/%s.%s?rev=%s>; rel="immutable"`,
331337
ctx.Repo.Repository.APIURL(),
332-
archiver.CommitID, archiver.CommitID))
338+
archiver.CommitID,
339+
archiver.Type.String(),
340+
archiver.CommitID,
341+
))
333342

334343
rPath := archiver.RelativePath()
335344
if setting.RepoArchive.Storage.ServeDirect() {

routers/common/markup.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,10 @@ func RenderMarkup(ctx *context.Base, ctxRepo *context.Repository, mode, text, ur
7777
rctx = rctx.WithMarkupType(markdown.MarkupName)
7878
case "comment":
7979
rctx = renderhelper.NewRenderContextRepoComment(ctx, repoModel, renderhelper.RepoCommentOptions{DeprecatedOwnerName: repoOwnerName, DeprecatedRepoName: repoName})
80+
rctx = rctx.WithMarkupType(markdown.MarkupName)
8081
case "wiki":
8182
rctx = renderhelper.NewRenderContextRepoWiki(ctx, repoModel, renderhelper.RepoWikiOptions{DeprecatedOwnerName: repoOwnerName, DeprecatedRepoName: repoName})
83+
rctx = rctx.WithMarkupType(markdown.MarkupName)
8284
case "file":
8385
rctx = renderhelper.NewRenderContextRepoFile(ctx, repoModel, renderhelper.RepoFileOptions{
8486
DeprecatedOwnerName: repoOwnerName, DeprecatedRepoName: repoName,

routers/web/repo/repo.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,12 @@ func RedirectDownload(ctx *context.Context) {
464464
// Download an archive of a repository
465465
func Download(ctx *context.Context) {
466466
uri := ctx.PathParam("*")
467-
aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, uri)
467+
ext, tp, err := archiver_service.ParseFileName(uri)
468+
if err != nil {
469+
ctx.ServerError("ParseFileName", err)
470+
return
471+
}
472+
aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, strings.TrimSuffix(uri, ext), tp)
468473
if err != nil {
469474
if errors.Is(err, archiver_service.ErrUnknownArchiveFormat{}) {
470475
ctx.Error(http.StatusBadRequest, err.Error())
@@ -523,7 +528,12 @@ func download(ctx *context.Context, archiveName string, archiver *repo_model.Rep
523528
// kind of drop it on the floor if this is the case.
524529
func InitiateDownload(ctx *context.Context) {
525530
uri := ctx.PathParam("*")
526-
aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, uri)
531+
ext, tp, err := archiver_service.ParseFileName(uri)
532+
if err != nil {
533+
ctx.ServerError("ParseFileName", err)
534+
return
535+
}
536+
aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, strings.TrimSuffix(uri, ext), tp)
527537
if err != nil {
528538
ctx.ServerError("archiver_service.NewRequest", err)
529539
return

services/repository/archiver/archiver.go

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -67,30 +67,36 @@ func (e RepoRefNotFoundError) Is(err error) bool {
6767
return ok
6868
}
6969

70-
// NewRequest creates an archival request, based on the URI. The
71-
// resulting ArchiveRequest is suitable for being passed to Await()
72-
// if it's determined that the request still needs to be satisfied.
73-
func NewRequest(repoID int64, repo *git.Repository, uri string) (*ArchiveRequest, error) {
74-
r := &ArchiveRequest{
75-
RepoID: repoID,
76-
}
77-
78-
var ext string
70+
func ParseFileName(uri string) (ext string, tp git.ArchiveType, err error) {
7971
switch {
8072
case strings.HasSuffix(uri, ".zip"):
8173
ext = ".zip"
82-
r.Type = git.ZIP
74+
tp = git.ZIP
8375
case strings.HasSuffix(uri, ".tar.gz"):
8476
ext = ".tar.gz"
85-
r.Type = git.TARGZ
77+
tp = git.TARGZ
8678
case strings.HasSuffix(uri, ".bundle"):
8779
ext = ".bundle"
88-
r.Type = git.BUNDLE
80+
tp = git.BUNDLE
8981
default:
90-
return nil, ErrUnknownArchiveFormat{RequestFormat: uri}
82+
return "", 0, ErrUnknownArchiveFormat{RequestFormat: uri}
83+
}
84+
return ext, tp, nil
85+
}
86+
87+
// NewRequest creates an archival request, based on the URI. The
88+
// resulting ArchiveRequest is suitable for being passed to Await()
89+
// if it's determined that the request still needs to be satisfied.
90+
func NewRequest(repoID int64, repo *git.Repository, refName string, fileType git.ArchiveType) (*ArchiveRequest, error) {
91+
if fileType < git.ZIP || fileType > git.BUNDLE {
92+
return nil, ErrUnknownArchiveFormat{RequestFormat: fileType.String()}
9193
}
9294

93-
r.refName = strings.TrimSuffix(uri, ext)
95+
r := &ArchiveRequest{
96+
RepoID: repoID,
97+
refName: refName,
98+
Type: fileType,
99+
}
94100

95101
// Get corresponding commit.
96102
commitID, err := repo.ConvertToGitID(r.refName)

0 commit comments

Comments
 (0)