From 9b416b2e36a035672226d4b83c6b7e87578b17fe Mon Sep 17 00:00:00 2001 From: Yoan Blanc Date: Thu, 6 Apr 2023 22:01:20 +0200 Subject: [PATCH] Use graceful editorconfig loader to reduce errors when loading malformed editorconfigs (#21257) The _graceful_ should fail less when the `.editorconfig` file isn't properly written, e.g. boolean values from YAML or unparseable numbers (when a number is expected). As is... information is lost as the _warning_ (a go-multierror.Error) is ignored. If anybody knows how to send them to the UI as warning; any help is appreciated. Closes #20694 Signed-off-by: Yoan Blanc --- modules/context/repo.go | 21 ++++++++++----------- routers/api/v1/repo/file.go | 2 +- routers/web/repo/editor.go | 2 +- routers/web/repo/middlewares.go | 2 +- routers/web/repo/view.go | 13 ++++++++++--- templates/repo/view_file.tmpl | 9 ++++++--- web_src/css/helpers.css | 1 + 7 files changed, 30 insertions(+), 20 deletions(-) diff --git a/modules/context/repo.go b/modules/context/repo.go index 820e756fb..9d45a6019 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -240,35 +240,34 @@ func (r *Repository) FileExists(path, branch string) (bool, error) { // GetEditorconfig returns the .editorconfig definition if found in the // HEAD of the default repo branch. -func (r *Repository) GetEditorconfig(optCommit ...*git.Commit) (*editorconfig.Editorconfig, error) { +func (r *Repository) GetEditorconfig(optCommit ...*git.Commit) (cfg *editorconfig.Editorconfig, warning, err error) { if r.GitRepo == nil { - return nil, nil + return nil, nil, nil } - var ( - err error - commit *git.Commit - ) + + var commit *git.Commit + if len(optCommit) != 0 { commit = optCommit[0] } else { commit, err = r.GitRepo.GetBranchCommit(r.Repository.DefaultBranch) if err != nil { - return nil, err + return nil, nil, err } } treeEntry, err := commit.GetTreeEntryByPath(".editorconfig") if err != nil { - return nil, err + return nil, nil, err } if treeEntry.Blob().Size() >= setting.UI.MaxDisplayFileSize { - return nil, git.ErrNotExist{ID: "", RelPath: ".editorconfig"} + return nil, nil, git.ErrNotExist{ID: "", RelPath: ".editorconfig"} } reader, err := treeEntry.Blob().DataAsync() if err != nil { - return nil, err + return nil, nil, err } defer reader.Close() - return editorconfig.Parse(reader) + return editorconfig.ParseGraceful(reader) } // RetrieveBaseRepo retrieves base repository diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index d5e8924f5..5f7ed255b 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -381,7 +381,7 @@ func GetEditorconfig(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" - ec, err := ctx.Repo.GetEditorconfig(ctx.Repo.Commit) + ec, _, err := ctx.Repo.GetEditorconfig(ctx.Repo.Commit) if err != nil { if git.IsErrNotExist(err) { ctx.NotFound(err) diff --git a/routers/web/repo/editor.go b/routers/web/repo/editor.go index f65e1ad3d..476c1d5dd 100644 --- a/routers/web/repo/editor.go +++ b/routers/web/repo/editor.go @@ -165,7 +165,7 @@ func editFile(ctx *context.Context, isNewFile bool) { // GetEditorConfig returns a editorconfig JSON string for given treePath or "null" func GetEditorConfig(ctx *context.Context, treePath string) string { - ec, err := ctx.Repo.GetEditorconfig() + ec, _, err := ctx.Repo.GetEditorconfig() if err == nil { def, err := ec.GetDefinitionForFilename(treePath) if err == nil { diff --git a/routers/web/repo/middlewares.go b/routers/web/repo/middlewares.go index 9a4aa3382..5c38b3115 100644 --- a/routers/web/repo/middlewares.go +++ b/routers/web/repo/middlewares.go @@ -19,7 +19,7 @@ func SetEditorconfigIfExists(ctx *context.Context) { return } - ec, err := ctx.Repo.GetEditorconfig() + ec, _, err := ctx.Repo.GetEditorconfig() if err != nil && !git.IsErrNotExist(err) { description := fmt.Sprintf("Error while getting .editorconfig file: %v", err) diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index ce60d9115..2a57f8ef3 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -346,11 +346,18 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st ctx.Data["RawFileLink"] = rawLink + "/" + util.PathEscapeSegments(ctx.Repo.TreePath) if ctx.Repo.TreePath == ".editorconfig" { - _, editorconfigErr := ctx.Repo.GetEditorconfig(ctx.Repo.Commit) - ctx.Data["FileError"] = editorconfigErr + _, editorconfigWarning, editorconfigErr := ctx.Repo.GetEditorconfig(ctx.Repo.Commit) + if editorconfigWarning != nil { + ctx.Data["FileWarning"] = strings.TrimSpace(editorconfigWarning.Error()) + } + if editorconfigErr != nil { + ctx.Data["FileError"] = strings.TrimSpace(editorconfigErr.Error()) + } } else if ctx.Repo.IsIssueConfig(ctx.Repo.TreePath) { _, issueConfigErr := ctx.Repo.GetIssueConfig(ctx.Repo.TreePath, ctx.Repo.Commit) - ctx.Data["FileError"] = issueConfigErr + if issueConfigErr != nil { + ctx.Data["FileError"] = strings.TrimSpace(issueConfigErr.Error()) + } } isDisplayingSource := ctx.FormString("display") == "source" diff --git a/templates/repo/view_file.tmpl b/templates/repo/view_file.tmpl index 70d33621c..36b50e0c7 100644 --- a/templates/repo/view_file.tmpl +++ b/templates/repo/view_file.tmpl @@ -1,9 +1,12 @@
{{- if .FileError}} +
+
{{.FileError}}
+
+ {{end}} + {{- if .FileWarning}}
-
-
{{.FileError}}
-
+
{{.FileWarning}}
{{end}}

diff --git a/web_src/css/helpers.css b/web_src/css/helpers.css index e2d195822..834a507b6 100644 --- a/web_src/css/helpers.css +++ b/web_src/css/helpers.css @@ -25,6 +25,7 @@ .gt-overflow-x-scroll { overflow-x: scroll !important; } .gt-cursor-default { cursor: default !important; } .gt-items-start { align-items: flex-start !important; } +.gt-whitespace-pre { white-space: pre !important } .gt-mono { font-family: var(--fonts-monospace) !important;