add comment about the sconf config file format at the top of the config files

hopefully this helps admins editing the file and prevent mistakes about config files.

for issue #56 by kikoreis, thanks!
This commit is contained in:
Mechiel Lukkien
2023-09-21 08:59:10 +02:00
parent 0d8603f9e1
commit 9534e464f9
8 changed files with 65 additions and 25 deletions

View File

@ -17,6 +17,7 @@ type writeError struct{ error }
type writer struct {
out *bufio.Writer
wrote int
prefix string
keepZero bool // If set, we also write zero values.
docs bool // If set, we write comments.
@ -33,8 +34,9 @@ func (w *writer) check(err error) {
}
func (w *writer) write(s string) {
_, err := w.out.WriteString(s)
n, err := w.out.WriteString(s)
w.check(err)
w.wrote += n
}
func (w *writer) flush() {
@ -108,7 +110,7 @@ func isEmptyStruct(v reflect.Value) bool {
for i := 0; i < n; i++ {
ft := t.Field(i)
tag := ft.Tag.Get("sconf")
if isIgnore(tag) {
if !ft.IsExported() || isIgnore(tag) {
continue
}
if !isOptional(tag) {
@ -134,7 +136,7 @@ func isZeroIgnored(v reflect.Value) bool {
for i := 0; i < n; i++ {
ft := t.Field(i)
tag := ft.Tag.Get("sconf")
if isIgnore(tag) {
if !ft.IsExported() || isIgnore(tag) {
continue
}
if !isZeroIgnored(v.Field(i)) {
@ -153,7 +155,7 @@ func (w *writer) describeStruct(v reflect.Value) {
for i := 0; i < n; i++ {
f := t.Field(i)
fv := v.Field(i)
if isIgnore(f.Tag.Get("sconf")) {
if !f.IsExported() || isIgnore(f.Tag.Get("sconf")) {
continue
}
if !w.keepZero && isOptional(f.Tag.Get("sconf")) && isZeroIgnored(fv) {
@ -163,11 +165,33 @@ func (w *writer) describeStruct(v reflect.Value) {
doc := f.Tag.Get("sconf-doc")
optional := isOptional(f.Tag.Get("sconf"))
if doc != "" || optional {
s := "\n" + w.prefix + "# " + doc
s := "\n"
if w.wrote == 0 {
// No empty line at start of file.
s = ""
}
// Treat two blank lines as section separator: the comments are not joined with
// lines with just "#", but instead with empty lines. To allow a hack where the
// first field of a config struct gives some context about the file.
sections := strings.Split(doc, "\n\n\n")
for si, section := range sections {
if si > 0 {
s += "\n\n\n"
}
for i, line := range strings.Split(section, "\n") {
if i > 0 {
s += "\n"
}
s += w.prefix + "#"
if line != "" {
s += " " + line
}
}
}
if optional {
opt := "(optional)"
if doc != "" {
opt = " " + opt
if !strings.HasSuffix(doc, " ") {
s += " "
}
s += opt
}

View File

@ -245,8 +245,8 @@ func (p *parser) parseStruct0(v reflect.Value) {
if vv == zeroValue {
p.stop(fmt.Sprintf("unknown key %q", k))
}
if ft, _ := t.FieldByName(k); isIgnore(ft.Tag.Get("sconf")) {
p.stop(fmt.Sprintf("unknown key %q (has ignore tag)", k))
if ft, _ := t.FieldByName(k); !ft.IsExported() || isIgnore(ft.Tag.Get("sconf")) {
p.stop(fmt.Sprintf("unknown key %q (has ignore tag or not exported)", k))
}
vv.Set(p.parseValue(vv))
}
@ -254,7 +254,7 @@ func (p *parser) parseStruct0(v reflect.Value) {
n := t.NumField()
for i := 0; i < n; i++ {
f := t.Field(i)
if isIgnore(f.Tag.Get("sconf")) || isOptional(f.Tag.Get("sconf")) {
if !f.IsExported() || isIgnore(f.Tag.Get("sconf")) || isOptional(f.Tag.Get("sconf")) {
continue
}
if _, ok := seen[f.Name]; !ok {

16
vendor/github.com/mjl-/xfmt/xfmt.go generated vendored
View File

@ -10,8 +10,12 @@ import (
// Config tells format how to reformat text.
type Config struct {
MaxWidth int // Max width of content (excluding indenting), after which lines are wrapped.
BreakPrefixes []string // String prefixes that cause a line to break, instead of being merged into the previous line.
// Max width of content (excluding indenting), after which lines are wrapped.
MaxWidth int
// String prefixes that cause a line to break, instead of being merged into the
// previous line.
BreakPrefixes []string
}
// Format reads text from r and writes reformatted text to w, according to
@ -33,7 +37,7 @@ type formatter struct {
curLineend string
}
type parseError error
type parseError struct{ error }
func (f *formatter) format() (rerr error) {
defer func() {
@ -65,7 +69,7 @@ func (f *formatter) format() (rerr error) {
func (f *formatter) check(err error, action string) {
if err != nil {
panic(parseError(fmt.Errorf("%s: %s", action, err)))
panic(parseError{fmt.Errorf("%s: %s", action, err)})
}
}
@ -108,6 +112,7 @@ func (f *formatter) gatherLine() (string, string) {
var curLine, curLineend string
var curPrefix string
n := 0
for {
line, end := f.peekLine()
if line == "" && end == "" {
@ -123,7 +128,7 @@ func (f *formatter) gatherLine() (string, string) {
}
break
}
if curLine != "" && (curPrefix != prefix || rem == "" || f.causeBreak(rem)) {
if n > 0 && (curPrefix != prefix || rem == "" || f.causeBreak(rem)) {
break
}
curPrefix = prefix
@ -136,6 +141,7 @@ func (f *formatter) gatherLine() (string, string) {
if curLine != "" && curLine[len(curLine)-1] < 0x20 {
break
}
n++
}
return curPrefix + curLine, curLineend