summaryrefslogtreecommitdiffstats
path: root/vendor/gopkg.in/ini.v1/ini.go
diff options
context:
space:
mode:
authorEthan Koenig <etk39@cornell.edu>2017-08-06 18:42:48 -0700
committerLunny Xiao <xiaolunwen@gmail.com>2017-08-07 09:42:48 +0800
commit27798c3efcfa002baf2d68a0fce23df7df16bcab (patch)
treee0b19caae4249477bd81c5866587d07c95aa1882 /vendor/gopkg.in/ini.v1/ini.go
parent54381f438b6dd3dcfd29426c003463b623d46982 (diff)
downloadgitea-27798c3efcfa002baf2d68a0fce23df7df16bcab.tar.gz
gitea-27798c3efcfa002baf2d68a0fce23df7df16bcab.zip
Temporarily patch go-ini/ini with fork (#2255)
Diffstat (limited to 'vendor/gopkg.in/ini.v1/ini.go')
-rw-r--r--vendor/gopkg.in/ini.v1/ini.go153
1 files changed, 104 insertions, 49 deletions
diff --git a/vendor/gopkg.in/ini.v1/ini.go b/vendor/gopkg.in/ini.v1/ini.go
index cd065e7822..84faae13bb 100644
--- a/vendor/gopkg.in/ini.v1/ini.go
+++ b/vendor/gopkg.in/ini.v1/ini.go
@@ -20,13 +20,12 @@ import (
"errors"
"fmt"
"io"
+ "io/ioutil"
"os"
"regexp"
"runtime"
- "strconv"
"strings"
"sync"
- "time"
)
const (
@@ -36,7 +35,7 @@ const (
// Maximum allowed depth when recursively substituing variable names.
_DEPTH_VALUES = 99
- _VERSION = "1.21.1"
+ _VERSION = "1.28.1"
)
// Version returns current package version literal.
@@ -59,6 +58,9 @@ var (
// Explicitly write DEFAULT section header
DefaultHeader = false
+
+ // Indicate whether to put a line between sections
+ PrettySection = true
)
func init() {
@@ -108,7 +110,16 @@ type sourceData struct {
}
func (s *sourceData) ReadCloser() (io.ReadCloser, error) {
- return &bytesReadCloser{bytes.NewReader(s.data)}, nil
+ return ioutil.NopCloser(bytes.NewReader(s.data)), nil
+}
+
+// sourceReadCloser represents an input stream with Close method.
+type sourceReadCloser struct {
+ reader io.ReadCloser
+}
+
+func (s *sourceReadCloser) ReadCloser() (io.ReadCloser, error) {
+ return s.reader, nil
}
// File represents a combination of a or more INI file(s) in memory.
@@ -149,6 +160,8 @@ func parseDataSource(source interface{}) (dataSource, error) {
return sourceFile{s}, nil
case []byte:
return &sourceData{s}, nil
+ case io.ReadCloser:
+ return &sourceReadCloser{s}, nil
default:
return nil, fmt.Errorf("error parsing data source: unknown type '%s'", s)
}
@@ -161,9 +174,16 @@ type LoadOptions struct {
Insensitive bool
// IgnoreContinuation indicates whether to ignore continuation lines while parsing.
IgnoreContinuation bool
+ // IgnoreInlineComment indicates whether to ignore comments at the end of value and treat it as part of value.
+ IgnoreInlineComment bool
// AllowBooleanKeys indicates whether to allow boolean type keys or treat as value is missing.
// This type of keys are mostly used in my.cnf.
AllowBooleanKeys bool
+ // AllowShadows indicates whether to keep track of keys with same name under same section.
+ AllowShadows bool
+ // Some INI formats allow group blocks that store a block of raw content that doesn't otherwise
+ // conform to key/value pairs. Specify the names of those blocks here.
+ UnparseableSections []string
}
func LoadSources(opts LoadOptions, source interface{}, others ...interface{}) (_ *File, err error) {
@@ -204,6 +224,12 @@ func InsensitiveLoad(source interface{}, others ...interface{}) (*File, error) {
return LoadSources(LoadOptions{Insensitive: true}, source, others...)
}
+// InsensitiveLoad has exactly same functionality as Load function
+// except it allows have shadow keys.
+func ShadowLoad(source interface{}, others ...interface{}) (*File, error) {
+ return LoadSources(LoadOptions{AllowShadows: true}, source, others...)
+}
+
// Empty returns an empty file object.
func Empty() *File {
// Ignore error here, we sure our data is good.
@@ -233,6 +259,18 @@ func (f *File) NewSection(name string) (*Section, error) {
return f.sections[name], nil
}
+// NewRawSection creates a new section with an unparseable body.
+func (f *File) NewRawSection(name, body string) (*Section, error) {
+ section, err := f.NewSection(name)
+ if err != nil {
+ return nil, err
+ }
+
+ section.isRawSection = true
+ section.rawBody = body
+ return section, nil
+}
+
// NewSections creates a list of sections.
func (f *File) NewSections(names ...string) (err error) {
for _, name := range names {
@@ -284,6 +322,11 @@ func (f *File) Sections() []*Section {
return sections
}
+// ChildSections returns a list of child sections of given section name.
+func (f *File) ChildSections(name string) []*Section {
+ return f.Section(name).ChildSections()
+}
+
// SectionStrings returns list of section names.
func (f *File) SectionStrings() []string {
list := make([]string, len(f.sectionList))
@@ -353,10 +396,7 @@ func (f *File) Append(source interface{}, others ...interface{}) error {
return f.Reload()
}
-// WriteToIndent writes content into io.Writer with given indention.
-// If PrettyFormat has been set to be true,
-// it will align "=" sign with spaces under each section.
-func (f *File) WriteToIndent(w io.Writer, indent string) (n int64, err error) {
+func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) {
equalSign := "="
if PrettyFormat {
equalSign = " = "
@@ -370,14 +410,14 @@ func (f *File) WriteToIndent(w io.Writer, indent string) (n int64, err error) {
if sec.Comment[0] != '#' && sec.Comment[0] != ';' {
sec.Comment = "; " + sec.Comment
}
- if _, err = buf.WriteString(sec.Comment + LineBreak); err != nil {
- return 0, err
+ if _, err := buf.WriteString(sec.Comment + LineBreak); err != nil {
+ return nil, err
}
}
if i > 0 || DefaultHeader {
- if _, err = buf.WriteString("[" + sname + "]" + LineBreak); err != nil {
- return 0, err
+ if _, err := buf.WriteString("[" + sname + "]" + LineBreak); err != nil {
+ return nil, err
}
} else {
// Write nothing if default section is empty
@@ -386,6 +426,13 @@ func (f *File) WriteToIndent(w io.Writer, indent string) (n int64, err error) {
}
}
+ if sec.isRawSection {
+ if _, err := buf.WriteString(sec.rawBody); err != nil {
+ return nil, err
+ }
+ continue
+ }
+
// Count and generate alignment length and buffer spaces using the
// longest key. Keys may be modifed if they contain certain characters so
// we need to take that into account in our calculation.
@@ -407,6 +454,7 @@ func (f *File) WriteToIndent(w io.Writer, indent string) (n int64, err error) {
}
alignSpaces := bytes.Repeat([]byte(" "), alignLength)
+ KEY_LIST:
for _, kname := range sec.keyList {
key := sec.Key(kname)
if len(key.Comment) > 0 {
@@ -416,8 +464,8 @@ func (f *File) WriteToIndent(w io.Writer, indent string) (n int64, err error) {
if key.Comment[0] != '#' && key.Comment[0] != ';' {
key.Comment = "; " + key.Comment
}
- if _, err = buf.WriteString(key.Comment + LineBreak); err != nil {
- return 0, err
+ if _, err := buf.WriteString(key.Comment + LineBreak); err != nil {
+ return nil, err
}
}
@@ -433,37 +481,55 @@ func (f *File) WriteToIndent(w io.Writer, indent string) (n int64, err error) {
case strings.Contains(kname, "`"):
kname = `"""` + kname + `"""`
}
- if _, err = buf.WriteString(kname); err != nil {
- return 0, err
- }
- if key.isBooleanType {
- continue
- }
+ for _, val := range key.ValueWithShadows() {
+ if _, err := buf.WriteString(kname); err != nil {
+ return nil, err
+ }
- // Write out alignment spaces before "=" sign
- if PrettyFormat {
- buf.Write(alignSpaces[:alignLength-len(kname)])
- }
+ if key.isBooleanType {
+ if kname != sec.keyList[len(sec.keyList)-1] {
+ buf.WriteString(LineBreak)
+ }
+ continue KEY_LIST
+ }
- val := key.value
- // In case key value contains "\n", "`", "\"", "#" or ";"
- if strings.ContainsAny(val, "\n`") {
- val = `"""` + val + `"""`
- } else if strings.ContainsAny(val, "#;") {
- val = "`" + val + "`"
- }
- if _, err = buf.WriteString(equalSign + val + LineBreak); err != nil {
- return 0, err
+ // Write out alignment spaces before "=" sign
+ if PrettyFormat {
+ buf.Write(alignSpaces[:alignLength-len(kname)])
+ }
+
+ // In case key value contains "\n", "`", "\"", "#" or ";"
+ if strings.ContainsAny(val, "\n`") {
+ val = `"""` + val + `"""`
+ } else if !f.options.IgnoreInlineComment && strings.ContainsAny(val, "#;") {
+ val = "`" + val + "`"
+ }
+ if _, err := buf.WriteString(equalSign + val + LineBreak); err != nil {
+ return nil, err
+ }
}
}
- // Put a line between sections
- if _, err = buf.WriteString(LineBreak); err != nil {
- return 0, err
+ if PrettySection {
+ // Put a line between sections
+ if _, err := buf.WriteString(LineBreak); err != nil {
+ return nil, err
+ }
}
}
+ return buf, nil
+}
+
+// WriteToIndent writes content into io.Writer with given indention.
+// If PrettyFormat has been set to be true,
+// it will align "=" sign with spaces under each section.
+func (f *File) WriteToIndent(w io.Writer, indent string) (int64, error) {
+ buf, err := f.writeToBuffer(indent)
+ if err != nil {
+ return 0, err
+ }
return buf.WriteTo(w)
}
@@ -476,23 +542,12 @@ func (f *File) WriteTo(w io.Writer) (int64, error) {
func (f *File) SaveToIndent(filename, indent string) error {
// Note: Because we are truncating with os.Create,
// so it's safer to save to a temporary file location and rename afte done.
- tmpPath := filename + "." + strconv.Itoa(time.Now().Nanosecond()) + ".tmp"
- defer os.Remove(tmpPath)
-
- fw, err := os.Create(tmpPath)
+ buf, err := f.writeToBuffer(indent);
if err != nil {
return err
}
- if _, err = f.WriteToIndent(fw, indent); err != nil {
- fw.Close()
- return err
- }
- fw.Close()
-
- // Remove old file and rename the new one.
- os.Remove(filename)
- return os.Rename(tmpPath, filename)
+ return ioutil.WriteFile(filename, buf.Bytes(), 0666)
}
// SaveTo writes content to file system.