summaryrefslogtreecommitdiffstats
path: root/routers
diff options
context:
space:
mode:
authorEarl Warren <earl-warren@noreply.codeberg.org>2025-01-07 07:17:49 +0100
committerEarl Warren <earl-warren@noreply.codeberg.org>2025-01-07 07:17:49 +0100
commit4261301dfb011278f349d748c579b384a18ae120 (patch)
tree7ce10ed27fe570ab3bd7af97ac00e99e8bcb8981 /routers
parentUpdate forgejo/forgejo-build-publish action to v5.3.0 (forgejo) (#6480) (diff)
parentchore(release-notes): notes for the week 2025-02 weekly cherry pick (diff)
downloadforgejo-4261301dfb011278f349d748c579b384a18ae120.tar.xz
forgejo-4261301dfb011278f349d748c579b384a18ae120.zip
[gitea] week 2025-02 cherry pick (gitea/main -> forgejo) (#6471)
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6471 Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Diffstat (limited to 'routers')
-rw-r--r--routers/api/packages/pypi/pypi.go47
-rw-r--r--routers/api/packages/pypi/pypi_test.go10
-rw-r--r--routers/api/v1/repo/file.go14
-rw-r--r--routers/web/org/projects.go6
-rw-r--r--routers/web/repo/download.go16
-rw-r--r--routers/web/repo/issue.go13
-rw-r--r--routers/web/repo/projects.go6
7 files changed, 78 insertions, 34 deletions
diff --git a/routers/api/packages/pypi/pypi.go b/routers/api/packages/pypi/pypi.go
index 7824db1823..9d8b60b4b4 100644
--- a/routers/api/packages/pypi/pypi.go
+++ b/routers/api/packages/pypi/pypi.go
@@ -10,6 +10,7 @@ import (
"regexp"
"sort"
"strings"
+ "unicode"
packages_model "code.gitea.io/gitea/models/packages"
packages_module "code.gitea.io/gitea/modules/packages"
@@ -139,9 +140,30 @@ func UploadPackageFile(ctx *context.Context) {
return
}
- projectURL := ctx.Req.FormValue("home_page")
- if !validation.IsValidURL(projectURL) {
- projectURL = ""
+ // Ensure ctx.Req.Form exists.
+ _ = ctx.Req.ParseForm()
+
+ var homepageURL string
+ projectURLs := ctx.Req.Form["project_urls"]
+ for _, purl := range projectURLs {
+ label, url, found := strings.Cut(purl, ",")
+ if !found {
+ continue
+ }
+ if normalizeLabel(label) != "homepage" {
+ continue
+ }
+ homepageURL = strings.TrimSpace(url)
+ break
+ }
+
+ if len(homepageURL) == 0 {
+ // TODO: Home-page is a deprecated metadata field. Remove this branch once it's no longer apart of the spec.
+ homepageURL = ctx.Req.FormValue("home_page")
+ }
+
+ if !validation.IsValidURL(homepageURL) {
+ homepageURL = ""
}
_, _, err = packages_service.CreatePackageOrAddFileToExisting(
@@ -160,7 +182,7 @@ func UploadPackageFile(ctx *context.Context) {
Description: ctx.Req.FormValue("description"),
LongDescription: ctx.Req.FormValue("long_description"),
Summary: ctx.Req.FormValue("summary"),
- ProjectURL: projectURL,
+ ProjectURL: homepageURL,
License: ctx.Req.FormValue("license"),
RequiresPython: ctx.Req.FormValue("requires_python"),
},
@@ -189,6 +211,23 @@ func UploadPackageFile(ctx *context.Context) {
ctx.Status(http.StatusCreated)
}
+// Normalizes a Project-URL label.
+// See https://packaging.python.org/en/latest/specifications/well-known-project-urls/#label-normalization.
+func normalizeLabel(label string) string {
+ var builder strings.Builder
+
+ // "A label is normalized by deleting all ASCII punctuation and whitespace, and then converting the result
+ // to lowercase."
+ for _, r := range label {
+ if unicode.IsPunct(r) || unicode.IsSpace(r) {
+ continue
+ }
+ builder.WriteRune(unicode.ToLower(r))
+ }
+
+ return builder.String()
+}
+
func isValidNameAndVersion(packageName, packageVersion string) bool {
return nameMatcher.MatchString(packageName) && versionMatcher.MatchString(packageVersion)
}
diff --git a/routers/api/packages/pypi/pypi_test.go b/routers/api/packages/pypi/pypi_test.go
index 3023692177..786105693f 100644
--- a/routers/api/packages/pypi/pypi_test.go
+++ b/routers/api/packages/pypi/pypi_test.go
@@ -36,3 +36,13 @@ func TestIsValidNameAndVersion(t *testing.T) {
assert.False(t, isValidNameAndVersion("test-name", "1.0.1aa"))
assert.False(t, isValidNameAndVersion("test-name", "1.0.0-alpha.beta"))
}
+
+func TestNormalizeLabel(t *testing.T) {
+ // Cases fetched from https://packaging.python.org/en/latest/specifications/well-known-project-urls/#label-normalization.
+ assert.Equal(t, "homepage", normalizeLabel("Homepage"))
+ assert.Equal(t, "homepage", normalizeLabel("Home-page"))
+ assert.Equal(t, "homepage", normalizeLabel("Home page"))
+ assert.Equal(t, "changelog", normalizeLabel("Change_Log"))
+ assert.Equal(t, "whatsnew", normalizeLabel("What's New?"))
+ assert.Equal(t, "github", normalizeLabel("github"))
+}
diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go
index 2cea538b72..55b245676d 100644
--- a/routers/api/v1/repo/file.go
+++ b/routers/api/v1/repo/file.go
@@ -11,7 +11,6 @@ import (
"fmt"
"io"
"net/http"
- "path"
"strings"
"time"
@@ -247,19 +246,14 @@ func getBlobForEntry(ctx *context.APIContext) (blob *git.Blob, entry *git.TreeEn
return nil, nil, nil
}
- info, _, err := git.Entries([]*git.TreeEntry{entry}).GetCommitsInfo(ctx, ctx.Repo.Commit, path.Dir("/" + ctx.Repo.TreePath)[1:])
+ latestCommit, err := ctx.Repo.GitRepo.GetTreePathLatestCommit(ctx.Repo.Commit.ID.String(), ctx.Repo.TreePath)
if err != nil {
- ctx.Error(http.StatusInternalServerError, "GetCommitsInfo", err)
+ ctx.Error(http.StatusInternalServerError, "GetTreePathLatestCommit", err)
return nil, nil, nil
}
+ when := &latestCommit.Committer.When
- if len(info) == 1 {
- // Not Modified
- lastModified = &info[0].Commit.Committer.When
- }
- blob = entry.Blob()
-
- return blob, entry, lastModified
+ return entry.Blob(), entry, when
}
// GetArchive get archive of a repository
diff --git a/routers/web/org/projects.go b/routers/web/org/projects.go
index 64d233fc45..32eb6eeef1 100644
--- a/routers/web/org/projects.go
+++ b/routers/web/org/projects.go
@@ -209,7 +209,7 @@ func ChangeProjectStatus(ctx *context.Context) {
ctx.NotFoundOrServerError("ChangeProjectStatusByRepoIDAndID", project_model.IsErrProjectNotExist, err)
return
}
- ctx.JSONRedirect(fmt.Sprintf("%s/-/projects/%d", ctx.ContextUser.HomeLink(), id))
+ ctx.JSONRedirect(project_model.ProjectLinkForOrg(ctx.ContextUser, id))
}
// DeleteProject delete a project
@@ -259,7 +259,7 @@ func RenderEditProject(ctx *context.Context) {
ctx.Data["redirect"] = ctx.FormString("redirect")
ctx.Data["HomeLink"] = ctx.ContextUser.HomeLink()
ctx.Data["card_type"] = p.CardType
- ctx.Data["CancelLink"] = fmt.Sprintf("%s/-/projects/%d", ctx.ContextUser.HomeLink(), p.ID)
+ ctx.Data["CancelLink"] = project_model.ProjectLinkForOrg(ctx.ContextUser, p.ID)
ctx.HTML(http.StatusOK, tplProjectsNew)
}
@@ -273,7 +273,7 @@ func EditProjectPost(ctx *context.Context) {
ctx.Data["PageIsViewProjects"] = true
ctx.Data["CanWriteProjects"] = canWriteProjects(ctx)
ctx.Data["CardTypes"] = project_model.GetCardConfig()
- ctx.Data["CancelLink"] = fmt.Sprintf("%s/-/projects/%d", ctx.ContextUser.HomeLink(), projectID)
+ ctx.Data["CancelLink"] = project_model.ProjectLinkForOrg(ctx.ContextUser, projectID)
shared_user.RenderUserHeader(ctx)
diff --git a/routers/web/repo/download.go b/routers/web/repo/download.go
index 1e87bbf015..d7fe368474 100644
--- a/routers/web/repo/download.go
+++ b/routers/web/repo/download.go
@@ -5,7 +5,6 @@
package repo
import (
- "path"
"time"
git_model "code.gitea.io/gitea/models/git"
@@ -82,7 +81,7 @@ func ServeBlobOrLFS(ctx *context.Context, blob *git.Blob, lastModified *time.Tim
return common.ServeBlob(ctx.Base, ctx.Repo.TreePath, blob, lastModified)
}
-func getBlobForEntry(ctx *context.Context) (blob *git.Blob, lastModified *time.Time) {
+func getBlobForEntry(ctx *context.Context) (*git.Blob, *time.Time) {
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath)
if err != nil {
if git.IsErrNotExist(err) {
@@ -98,19 +97,14 @@ func getBlobForEntry(ctx *context.Context) (blob *git.Blob, lastModified *time.T
return nil, nil
}
- info, _, err := git.Entries([]*git.TreeEntry{entry}).GetCommitsInfo(ctx, ctx.Repo.Commit, path.Dir("/" + ctx.Repo.TreePath)[1:])
+ latestCommit, err := ctx.Repo.GitRepo.GetTreePathLatestCommit(ctx.Repo.Commit.ID.String(), ctx.Repo.TreePath)
if err != nil {
- ctx.ServerError("GetCommitsInfo", err)
+ ctx.ServerError("GetTreePathLatestCommit", err)
return nil, nil
}
+ lastModified := &latestCommit.Committer.When
- if len(info) == 1 {
- // Not Modified
- lastModified = &info[0].Commit.Committer.When
- }
- blob = entry.Blob()
-
- return blob, lastModified
+ return entry.Blob(), lastModified
}
// SingleDownload download a file by repos path
diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go
index b537afdab5..61711095b9 100644
--- a/routers/web/repo/issue.go
+++ b/routers/web/repo/issue.go
@@ -1291,10 +1291,17 @@ func NewIssuePost(ctx *context.Context) {
log.Trace("Issue created: %d/%d", repo.ID, issue.ID)
if ctx.FormString("redirect_after_creation") == "project" && projectID > 0 {
- ctx.JSONRedirect(ctx.Repo.RepoLink + "/projects/" + strconv.FormatInt(projectID, 10))
- } else {
- ctx.JSONRedirect(issue.Link())
+ project, err := project_model.GetProjectByID(ctx, projectID)
+ if err == nil {
+ if project.Type == project_model.TypeOrganization {
+ ctx.JSONRedirect(project_model.ProjectLinkForOrg(ctx.Repo.Owner, project.ID))
+ } else {
+ ctx.JSONRedirect(project_model.ProjectLinkForRepo(repo, project.ID))
+ }
+ return
+ }
}
+ ctx.JSONRedirect(issue.Link())
}
// roleDescriptor returns the role descriptor for a comment in/with the given repo, poster and issue
diff --git a/routers/web/repo/projects.go b/routers/web/repo/projects.go
index f4b027dae1..55a422453f 100644
--- a/routers/web/repo/projects.go
+++ b/routers/web/repo/projects.go
@@ -183,7 +183,7 @@ func ChangeProjectStatus(ctx *context.Context) {
ctx.NotFoundOrServerError("ChangeProjectStatusByRepoIDAndID", project_model.IsErrProjectNotExist, err)
return
}
- ctx.JSONRedirect(fmt.Sprintf("%s/projects/%d", ctx.Repo.RepoLink, id))
+ ctx.JSONRedirect(project_model.ProjectLinkForRepo(ctx.Repo.Repository, id))
}
// DeleteProject delete a project
@@ -237,7 +237,7 @@ func RenderEditProject(ctx *context.Context) {
ctx.Data["content"] = p.Description
ctx.Data["card_type"] = p.CardType
ctx.Data["redirect"] = ctx.FormString("redirect")
- ctx.Data["CancelLink"] = fmt.Sprintf("%s/projects/%d", ctx.Repo.Repository.Link(), p.ID)
+ ctx.Data["CancelLink"] = project_model.ProjectLinkForRepo(ctx.Repo.Repository, p.ID)
ctx.HTML(http.StatusOK, tplProjectsNew)
}
@@ -251,7 +251,7 @@ func EditProjectPost(ctx *context.Context) {
ctx.Data["PageIsEditProjects"] = true
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
ctx.Data["CardTypes"] = project_model.GetCardConfig()
- ctx.Data["CancelLink"] = fmt.Sprintf("%s/projects/%d", ctx.Repo.Repository.Link(), projectID)
+ ctx.Data["CancelLink"] = project_model.ProjectLinkForRepo(ctx.Repo.Repository, projectID)
if ctx.HasError() {
ctx.HTML(http.StatusOK, tplProjectsNew)