mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
commands, hugolib: Get file context in "config parse failed" errors
Fixes #5325
This commit is contained in:
parent
2bf686ee21
commit
ed7b3e2619
8 changed files with 35 additions and 21 deletions
|
@ -662,9 +662,10 @@ func (c *commandeer) fullRebuild() {
|
||||||
c.commandeerHugoState = &commandeerHugoState{}
|
c.commandeerHugoState = &commandeerHugoState{}
|
||||||
err := c.loadConfig(true, true)
|
err := c.loadConfig(true, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.logger.ERROR.Println("Failed to reload config:", err)
|
|
||||||
// Set the processing on pause until the state is recovered.
|
// Set the processing on pause until the state is recovered.
|
||||||
c.paused = true
|
c.paused = true
|
||||||
|
c.handleBuildErr(err, "Failed to reload config")
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
c.paused = false
|
c.paused = false
|
||||||
}
|
}
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -63,7 +63,6 @@ require (
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e // indirect
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e // indirect
|
||||||
golang.org/x/text v0.3.0
|
golang.org/x/text v0.3.0
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0
|
|
||||||
gopkg.in/yaml.v2 v2.2.1
|
gopkg.in/yaml.v2 v2.2.1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
3
go.sum
3
go.sum
|
@ -65,7 +65,6 @@ github.com/magefile/mage v1.4.0 h1:RI7B1CgnPAuu2O9lWszwya61RLmfL0KCdo+QyyI/Bhk=
|
||||||
github.com/magefile/mage v1.4.0/go.mod h1:IUDi13rsHje59lecXokTfGX0QIzO45uVPlXnJYsXepA=
|
github.com/magefile/mage v1.4.0/go.mod h1:IUDi13rsHje59lecXokTfGX0QIzO45uVPlXnJYsXepA=
|
||||||
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
|
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
|
||||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
github.com/markbates/inflect v0.0.0-20171215194931-a12c3aec81a6 h1:LZhVjIISSbj8qLf2qDPP0D8z0uvOWAW5C85ly5mJW6c=
|
|
||||||
github.com/markbates/inflect v0.0.0-20171215194931-a12c3aec81a6/go.mod h1:oTeZL2KHA7CUX6X+fovmK9OvIOFuqu0TwdQrZjLTh88=
|
github.com/markbates/inflect v0.0.0-20171215194931-a12c3aec81a6/go.mod h1:oTeZL2KHA7CUX6X+fovmK9OvIOFuqu0TwdQrZjLTh88=
|
||||||
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
|
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
|
||||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
|
@ -146,7 +145,5 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0 h1:POO/ycCATvegFmVuPpQzZFJ+pGZeX22Ufu6fibxDVjU=
|
|
||||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
|
|
||||||
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
|
|
@ -16,10 +16,11 @@ package hugolib
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gohugoio/hugo/common/herrors"
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/hugolib/paths"
|
"github.com/gohugoio/hugo/hugolib/paths"
|
||||||
_errors "github.com/pkg/errors"
|
_errors "github.com/pkg/errors"
|
||||||
|
|
||||||
|
@ -106,12 +107,23 @@ func LoadConfig(d ConfigSourceDescriptor, doWithConfig ...func(cfg config.Provid
|
||||||
v.SetConfigFile(configFilenames[0])
|
v.SetConfigFile(configFilenames[0])
|
||||||
v.AddConfigPath(d.Path)
|
v.AddConfigPath(d.Path)
|
||||||
|
|
||||||
|
applyFileContext := func(filename string, err error) error {
|
||||||
|
err, _ = herrors.WithFileContextForFile(
|
||||||
|
err,
|
||||||
|
filename,
|
||||||
|
filename,
|
||||||
|
fs,
|
||||||
|
herrors.SimpleLineMatcher)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
var configFileErr error
|
var configFileErr error
|
||||||
|
|
||||||
err := v.ReadInConfig()
|
err := v.ReadInConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if _, ok := err.(viper.ConfigParseError); ok {
|
if _, ok := err.(viper.ConfigParseError); ok {
|
||||||
return nil, configFiles, err
|
return nil, configFiles, applyFileContext(v.ConfigFileUsed(), err)
|
||||||
}
|
}
|
||||||
configFileErr = ErrNoConfigFile
|
configFileErr = ErrNoConfigFile
|
||||||
}
|
}
|
||||||
|
@ -129,7 +141,7 @@ func LoadConfig(d ConfigSourceDescriptor, doWithConfig ...func(cfg config.Provid
|
||||||
return nil, configFiles, fmt.Errorf("Unable to open Config file.\n (%s)\n", err)
|
return nil, configFiles, fmt.Errorf("Unable to open Config file.\n (%s)\n", err)
|
||||||
}
|
}
|
||||||
if err = v.MergeConfig(r); err != nil {
|
if err = v.MergeConfig(r); err != nil {
|
||||||
return nil, configFiles, fmt.Errorf("Unable to parse/merge Config file (%s).\n (%s)\n", configFile, err)
|
return nil, configFiles, applyFileContext(configFile, err)
|
||||||
}
|
}
|
||||||
configFiles = append(configFiles, configFile)
|
configFiles = append(configFiles, configFile)
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ func (t testSiteBuildErrorAsserter) assertLineNumber(lineNumber int, err error)
|
||||||
func (t testSiteBuildErrorAsserter) assertErrorMessage(e1, e2 string) {
|
func (t testSiteBuildErrorAsserter) assertErrorMessage(e1, e2 string) {
|
||||||
// The error message will contain filenames with OS slashes. Normalize before compare.
|
// The error message will contain filenames with OS slashes. Normalize before compare.
|
||||||
e1, e2 = filepath.ToSlash(e1), filepath.ToSlash(e2)
|
e1, e2 = filepath.ToSlash(e1), filepath.ToSlash(e2)
|
||||||
t.assert.Equal(e1, e2, trace())
|
t.assert.Contains(e2, e1, trace())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,8 +102,8 @@ func TestSiteBuildErrors(t *testing.T) {
|
||||||
fe := a.getFileError(err)
|
fe := a.getFileError(err)
|
||||||
assert.Equal(5, fe.LineNumber)
|
assert.Equal(5, fe.LineNumber)
|
||||||
assert.Equal(14, fe.ColumnNumber)
|
assert.Equal(14, fe.ColumnNumber)
|
||||||
assert.Equal("md", fe.ChromaLexer)
|
assert.Equal("go-html-template", fe.ChromaLexer)
|
||||||
a.assertErrorMessage("asdfadf", fe.Error())
|
a.assertErrorMessage("\"layouts/_default/single.html:5:14\": execute of template failed", fe.Error())
|
||||||
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -124,7 +124,12 @@ func TestSiteBuildErrors(t *testing.T) {
|
||||||
return strings.Replace(content, ".Title", ".Titles", 1)
|
return strings.Replace(content, ".Title", ".Titles", 1)
|
||||||
},
|
},
|
||||||
assertBuildError: func(a testSiteBuildErrorAsserter, err error) {
|
assertBuildError: func(a testSiteBuildErrorAsserter, err error) {
|
||||||
a.assertLineNumber(4, err)
|
fe := a.getFileError(err)
|
||||||
|
assert.Equal(7, fe.LineNumber)
|
||||||
|
assert.Equal("md", fe.ChromaLexer)
|
||||||
|
// Make sure that it contains both the content file and template
|
||||||
|
a.assertErrorMessage(`content/myyaml.md:7:10": failed to render shortcode "sc"`, fe.Error())
|
||||||
|
a.assertErrorMessage(`shortcodes/sc.html:4:22: executing "shortcodes/sc.html" at <.Page.Titles>: can't evaluate`, fe.Error())
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -173,7 +178,7 @@ func TestSiteBuildErrors(t *testing.T) {
|
||||||
},
|
},
|
||||||
assertBuildError: func(a testSiteBuildErrorAsserter, err error) {
|
assertBuildError: func(a testSiteBuildErrorAsserter, err error) {
|
||||||
assert.Error(err)
|
assert.Error(err)
|
||||||
assert.Contains(err.Error(), "single.html")
|
assert.Contains(err.Error(), `"content/mytoml.md": render of "page" failed: execute of template failed: panic in Execute`)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,7 +132,7 @@ func TestPageBundlerSiteRegular(t *testing.T) {
|
||||||
assert.Len(pageResources, 2)
|
assert.Len(pageResources, 2)
|
||||||
firstPage := pageResources[0].(*Page)
|
firstPage := pageResources[0].(*Page)
|
||||||
secondPage := pageResources[1].(*Page)
|
secondPage := pageResources[1].(*Page)
|
||||||
assert.Equal(filepath.FromSlash("base/b/my-bundle/1.md"), firstPage.pathOrTitle(), secondPage.pathOrTitle())
|
assert.Equal(filepath.FromSlash("/work/base/b/my-bundle/1.md"), firstPage.pathOrTitle(), secondPage.pathOrTitle())
|
||||||
assert.Contains(firstPage.content(), "TheContent")
|
assert.Contains(firstPage.content(), "TheContent")
|
||||||
assert.Equal(6, len(leafBundle1.Resources))
|
assert.Equal(6, len(leafBundle1.Resources))
|
||||||
|
|
||||||
|
|
|
@ -1145,7 +1145,7 @@ func TestDegenerateInvalidFrontMatterShortDelim(t *testing.T) {
|
||||||
r string
|
r string
|
||||||
err string
|
err string
|
||||||
}{
|
}{
|
||||||
{invalidFrontmatterShortDelimEnding, ":2: EOF looking for end YAML front matter delimiter"},
|
{invalidFrontmatterShortDelimEnding, "EOF looking for end YAML front matter delimiter"},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
s := newTestSite(t)
|
s := newTestSite(t)
|
||||||
|
|
|
@ -368,11 +368,11 @@ func TestExtractShortcodes(t *testing.T) {
|
||||||
expectErrorMsg string
|
expectErrorMsg string
|
||||||
}{
|
}{
|
||||||
{"text", "Some text.", "map[]", "Some text.", ""},
|
{"text", "Some text.", "map[]", "Some text.", ""},
|
||||||
{"invalid right delim", "{{< tag }}", "", false, ":5:.*unrecognized character.*}"},
|
{"invalid right delim", "{{< tag }}", "", false, "unrecognized character"},
|
||||||
{"invalid close", "\n{{< /tag >}}", "", false, ":6:.*got closing shortcode, but none is open"},
|
{"invalid close", "\n{{< /tag >}}", "", false, "got closing shortcode, but none is open"},
|
||||||
{"invalid close2", "\n\n{{< tag >}}{{< /anotherTag >}}", "", false, ":7: closing tag for shortcode 'anotherTag' does not match start tag"},
|
{"invalid close2", "\n\n{{< tag >}}{{< /anotherTag >}}", "", false, "closing tag for shortcode 'anotherTag' does not match start tag"},
|
||||||
{"unterminated quote 1", `{{< figure src="im caption="S" >}}`, "", false, ":5:.got pos.*"},
|
{"unterminated quote 1", `{{< figure src="im caption="S" >}}`, "", false, "got pos"},
|
||||||
{"unterminated quote 1", `{{< figure src="im" caption="S >}}`, "", false, ":5:.*unterm.*}"},
|
{"unterminated quote 1", `{{< figure src="im" caption="S >}}`, "", false, "unterm"},
|
||||||
{"one shortcode, no markup", "{{< tag >}}", "", testScPlaceholderRegexp, ""},
|
{"one shortcode, no markup", "{{< tag >}}", "", testScPlaceholderRegexp, ""},
|
||||||
{"one shortcode, markup", "{{% tag %}}", "", testScPlaceholderRegexp, ""},
|
{"one shortcode, markup", "{{% tag %}}", "", testScPlaceholderRegexp, ""},
|
||||||
{"one pos param", "{{% tag param1 %}}", `tag([\"param1\"], true){[]}"]`, testScPlaceholderRegexp, ""},
|
{"one pos param", "{{% tag param1 %}}", `tag([\"param1\"], true){[]}"]`, testScPlaceholderRegexp, ""},
|
||||||
|
@ -430,7 +430,7 @@ func TestExtractShortcodes(t *testing.T) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("[%d] %s: ExtractShortcodes didn't return an expected error", i, this.name)
|
t.Fatalf("[%d] %s: ExtractShortcodes didn't return an expected error", i, this.name)
|
||||||
} else {
|
} else {
|
||||||
r, _ := regexp.Compile(this.expectErrorMsg)
|
r := regexp.MustCompile(this.expectErrorMsg)
|
||||||
if !r.MatchString(err.Error()) {
|
if !r.MatchString(err.Error()) {
|
||||||
t.Fatalf("[%d] %s: ExtractShortcodes didn't return an expected error message, got\n%s but expected\n%s",
|
t.Fatalf("[%d] %s: ExtractShortcodes didn't return an expected error message, got\n%s but expected\n%s",
|
||||||
i, this.name, err.Error(), this.expectErrorMsg)
|
i, this.name, err.Error(), this.expectErrorMsg)
|
||||||
|
|
Loading…
Reference in a new issue