diff options
author | Ethan Koenig <etk39@cornell.edu> | 2017-08-06 18:42:48 -0700 |
---|---|---|
committer | Lunny Xiao <xiaolunwen@gmail.com> | 2017-08-07 09:42:48 +0800 |
commit | 27798c3efcfa002baf2d68a0fce23df7df16bcab (patch) | |
tree | e0b19caae4249477bd81c5866587d07c95aa1882 /vendor/gopkg.in/ini.v1/ini.go | |
parent | 54381f438b6dd3dcfd29426c003463b623d46982 (diff) | |
download | gitea-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.go | 153 |
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. |