mirror of
https://github.com/go-gitea/gitea.git
synced 2026-10-28 16:47:01 +09:00
fix(repo): use the viewed ref's editorconfig in file view, blame and editor (#39973)
The file view, blame and web editor read `.editorconfig` from the default branch, so branch-specific settings like tab width were ignored. The file view's middleware ran before the ref was resolved, and blame never loaded it. - `GetEditorconfig` reads the current commit, falling back to the default branch only where no ref is resolved - `Home` and `RefBlame` load the editorconfig after ref resolution Fixes: https://github.com/go-gitea/gitea/issues/27413 Signed-off-by: silverwind <me@silverwind.io> Co-authored-by: silverwind <me@silverwind.io>
This commit is contained in:
1 parent
f10f7e7f91
commit
257c34e003
8 files changed
+30
-22
No files matched your search
@@ -299,7 +299,7 @@ func GetEditorconfig(ctx *context.APIContext) {
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
ec, _, err := ctx.Repo.GetEditorconfig(ctx, ctx.Repo.Commit)
|
||||
ec, _, err := ctx.Repo.GetEditorconfig(ctx)
|
||||
if err != nil {
|
||||
ctx.APIErrorAuto(err)
|
||||
return
|
||||
|
||||
@@ -94,6 +94,7 @@ func RefBlame(ctx *context.Context) {
|
||||
}
|
||||
|
||||
renderBlame(ctx, result.Parts, commitNames)
|
||||
SetEditorconfigIfExists(ctx)
|
||||
|
||||
ctx.HTML(http.StatusOK, tplName)
|
||||
}
|
||||
|
||||
@@ -169,7 +169,7 @@ func prepareFileView(ctx *context.Context, entry *git.TreeEntry) {
|
||||
ctx.Data["RawFileLink"] = ctx.Repo.RepoLink + "/raw/" + ctx.Repo.RefTypeNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
|
||||
|
||||
if ctx.Repo.TreePath == ".editorconfig" {
|
||||
_, editorconfigWarning, editorconfigErr := ctx.Repo.GetEditorconfig(ctx, ctx.Repo.Commit)
|
||||
_, editorconfigWarning, editorconfigErr := ctx.Repo.GetEditorconfig(ctx)
|
||||
if editorconfigWarning != nil {
|
||||
ctx.Data["FileWarning"] = strings.TrimSpace(editorconfigWarning.Error())
|
||||
}
|
||||
|
||||
@@ -477,6 +477,7 @@ func Home(ctx *context.Context) {
|
||||
prepareFuncs := []func(*context.Context){
|
||||
prepareClonePanel,
|
||||
prepareHomeSidebarRepoTopics,
|
||||
SetEditorconfigIfExists,
|
||||
prepareToRenderDirOrFile(entry),
|
||||
prepareRecentlyPushedNewBranches,
|
||||
}
|
||||
|
||||
+2
-2
@@ -1298,7 +1298,7 @@ func registerWebRoutes(m *web.Router, webAuth *AuthMiddleware) {
|
||||
// end "/{username}/{reponame}/settings"
|
||||
|
||||
// user/org home, including rss feeds like "/{username}/{reponame}.rss"
|
||||
m.Get("/{username}/{reponame}", optSignIn, webAuth.AllowBasic, context.RepoAssignment, context.RepoRefByType(git.RefTypeBranch), repo.SetEditorconfigIfExists, repo.Home)
|
||||
m.Get("/{username}/{reponame}", optSignIn, webAuth.AllowBasic, context.RepoAssignment, context.RepoRefByType(git.RefTypeBranch), repo.Home)
|
||||
|
||||
m.Post("/{username}/{reponame}/markup", optSignIn, context.RepoAssignment, reqUnitsWithMarkdown, web.Bind[*structs.MarkupOption](), misc.Markup)
|
||||
|
||||
@@ -1761,7 +1761,7 @@ func registerWebRoutes(m *web.Router, webAuth *AuthMiddleware) {
|
||||
m.Get("/tag/*", context.RepoRefByType(git.RefTypeTag), repo.Home)
|
||||
m.Get("/commit/*", context.RepoRefByType(git.RefTypeCommit), repo.Home)
|
||||
m.Get("/*", context.RepoRefByType(""), repo.Home) // "/*" route is deprecated, and kept for backward compatibility
|
||||
}, repo.SetEditorconfigIfExists)
|
||||
})
|
||||
m.Get("/tree/*", repo.RedirectRepoTreeToSrc) // redirect "/owner/repo/tree/*" requests to "/owner/repo/src/*"
|
||||
m.Get("/blob/*", repo.RedirectRepoBlobToCommit) // redirect "/owner/repo/blob/*" requests to "/owner/repo/src/commit/*"
|
||||
|
||||
|
||||
@@ -307,18 +307,14 @@ func (r *Repository) RefTypeNameSubURL() string {
|
||||
return r.RefFullName.RefWebLinkPath()
|
||||
}
|
||||
|
||||
// GetEditorconfig returns the .editorconfig definition if found in the
|
||||
// HEAD of the default repo branch.
|
||||
func (r *Repository) GetEditorconfig(ctx context.Context, optCommit ...*git.Commit) (cfg *editorconfig.Editorconfig, warning, err error) {
|
||||
// GetEditorconfig returns the .editorconfig of the current commit, falling back to the default branch
|
||||
func (r *Repository) GetEditorconfig(ctx context.Context) (cfg *editorconfig.Editorconfig, warning, err error) {
|
||||
if r.GitRepo == nil {
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
var commit *git.Commit
|
||||
|
||||
if len(optCommit) != 0 {
|
||||
commit = optCommit[0]
|
||||
} else {
|
||||
commit := r.Commit
|
||||
if commit == nil {
|
||||
commit, err = r.GitRepo.GetBranchCommit(ctx, r.Repository.DefaultBranch)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
import {env} from 'node:process';
|
||||
import {expect, test} from '@playwright/test';
|
||||
import {login, apiCreateRepo, randomString} from './utils.ts';
|
||||
import {login, apiCreateFiles, apiCreateRepo, randomString} from './utils.ts';
|
||||
|
||||
test('codeeditor textarea updates correctly', async ({page, request}) => {
|
||||
const repoName = `e2e-codeeditor-${randomString(8)}`;
|
||||
await Promise.all([apiCreateRepo(request, {name: repoName}), login(page)]);
|
||||
await page.goto(`/${env.GITEA_TEST_E2E_USER}/${repoName}/_new/main`);
|
||||
await page.getByPlaceholder('Name your file…').fill('test.js');
|
||||
await expect(page.locator('[data-tab="write"] .editor-loading')).toBeHidden();
|
||||
const editor = page.locator('.cm-content[role="textbox"]');
|
||||
await expect(editor).toBeVisible();
|
||||
await editor.click();
|
||||
await page.keyboard.type('const hello = "world";');
|
||||
await expect(page.locator('textarea[name="content"]')).toHaveValue('const hello = "world";');
|
||||
const owner = env.GITEA_TEST_E2E_USER;
|
||||
await Promise.all([
|
||||
(async () => {
|
||||
await apiCreateRepo(request, {name: repoName});
|
||||
await apiCreateFiles(request, owner, repoName, [{path: '.editorconfig', content: '[*]\nindent_size = 2\n'}], {newBranch: 'feature'});
|
||||
})(),
|
||||
login(page),
|
||||
]);
|
||||
await page.goto(`/${owner}/${repoName}/_new/feature`);
|
||||
await page.locator('.cm-content[role="textbox"]').click();
|
||||
await page.keyboard.press('Tab');
|
||||
await expect(page.locator('textarea[name="content"]')).toHaveValue(' ');
|
||||
});
|
||||
@@ -39,6 +39,13 @@ func TestEditor(t *testing.T) {
|
||||
testEditFile(t, sessionUser2, "user2", "repo1", "master", "README.md", "Hello, World (direct)\n")
|
||||
testEditFileToNewBranch(t, sessionUser2, "user2", "repo1", "master", "feature/test", "README.md", "Hello, World (commit-to-new-branch)\n")
|
||||
})
|
||||
t.Run("EditorconfigOfBranch", func(t *testing.T) {
|
||||
testCreateFile(t, sessionUser2, "user2", "repo1", "master", "editorconfig", ".editorconfig", "[*]\nindent_size = 2\n")
|
||||
for _, link := range []string{"/user2/repo1/src/branch/editorconfig/README.md", "/user2/repo1/blame/branch/editorconfig/README.md"} {
|
||||
resp := sessionUser2.MakeRequest(t, NewRequest(t, "GET", link), http.StatusOK)
|
||||
AssertHTMLElement(t, NewHTMLParser(t, resp.Body), ".tab-size-2", true)
|
||||
}
|
||||
})
|
||||
t.Run("PatchFile", testEditorPatchFile)
|
||||
t.Run("DeleteFile", func(t *testing.T) {
|
||||
viewLink := "/user2/repo1/src/branch/branch2/README.md"
|
||||
|
||||
Reference in new issue
Block a user