Documentation
¶
Overview ¶
Package ini implements a lossless reader and writer for the INI dialect used by the OpenSVC configuration files.
The parse tree keeps a reference to the source bytes each element was produced from. Elements left untouched are written back verbatim, so writing a document nobody modified reproduces the input byte for byte, comments, blank lines, alignment and multiline layout included. Only the elements actually modified are re-encoded.
This is what lets "config edit" round trip a configuration file through the daemon without reformatting it, and lets a value be replaced in place, as "config show --redact-secrets" needs.
Index ¶
- Constants
- func Unquote(s string) string
- type File
- func (f *File) Bytes() ([]byte, error)
- func (f *File) DeleteSection(name string)
- func (f *File) GetSection(name string) (*Section, error)
- func (f *File) HasSection(name string) bool
- func (f *File) MaterializeDefaultSection()
- func (f *File) NewSection(name string) (*Section, error)
- func (f *File) Options() Options
- func (f *File) Reload() error
- func (f *File) Section(name string) *Section
- func (f *File) SectionStrings() []string
- func (f *File) Sections() []*Section
- func (f *File) String() string
- func (f *File) WriteTo(w io.Writer) (int64, error)
- type Format
- type Key
- type Options
- type Section
- func (s *Section) DeleteKey(name string)
- func (s *Section) GetKey(name string) (*Key, error)
- func (s *Section) HasKey(name string) bool
- func (s *Section) Key(name string) *Key
- func (s *Section) KeyStrings() []string
- func (s *Section) Keys() []*Key
- func (s *Section) KeysHash() map[string]string
- func (s *Section) Name() string
- func (s *Section) NewKey(name, value string) (*Key, error)
- type Writer
Constants ¶
const ( // DefaultSection is the name of the section holding the keys defined // before the first section header. DefaultSection = "DEFAULT" )
Variables ¶
This section is empty.
Functions ¶
func Unquote ¶
Unquote strips the surrounding quote pair a value would be stripped of when read from a document, so a value given on a command line and the same value written in a document mean the same thing.
The pair is stripped only when the quote appears nowhere else in the value, which is the rule the parser follows.
Types ¶
type File ¶
type File struct {
// Format tunes the encoding of the added and modified elements.
Format Format
// contains filtered or unexported fields
}
File is a parsed INI document.
The document is held as an ordered list of nodes, one per section header and one per key, each keeping the source bytes it was parsed from. Sections and keys are indexes over that list.
func Load ¶
Load parses the given sources into a single document.
A source is either a file path, as a string, or the document bytes, as a []byte. Sources are merged in order: a key redefined by a later source keeps its first position and takes the later value.
Writing back is byte-identical only when the document was loaded from a single source, which is the case of every document OpenSVC writes back.
func (*File) DeleteSection ¶
DeleteSection removes the named section and all its keys.
func (*File) GetSection ¶
GetSection returns the named section, or an error when it does not exist.
func (*File) HasSection ¶
HasSection reports whether the named section exists.
func (*File) MaterializeDefaultSection ¶
func (f *File) MaterializeDefaultSection()
MaterializeDefaultSection gives the default section a header to encode when it has none, so the document is written with the "[DEFAULT]" line and the keys of the default section are visibly grouped under it.
The default section of a parsed document has no header when the source had none: the keys defined before the first section header are its keys, and the document is written back without a header it never had. Materializing the header inserts it at the head of the document, before those keys.
A document that already has a default section header is left untouched, and so is its byte-identical write back. The header is encoded only when Format.DefaultHeader is set, which it is by default.
func (*File) NewSection ¶
NewSection returns the named section, creating it when it does not exist.
func (*File) SectionStrings ¶
SectionStrings returns the section names, in document order.
type Format ¶
type Format struct {
// KeyValueDelimiter is written between a key name and its value,
// surrounding spaces included. Defaults to " = ".
KeyValueDelimiter string
// LineBreak terminates a written line. Defaults to "\n".
LineBreak string
// DefaultHeader writes the default section header of a document
// created empty. A parsed document is written back with the header
// it had, or without one if it had none.
DefaultHeader bool
// BlankLineBeforeSection writes a blank line before an encoded
// section header, so the sections of a document built from scratch
// are separated. It writes none before the header heading the
// document, and none where a blank line already stands.
//
// Like the rest of Format it only applies to an encoded header: a
// section header written back from its source bytes keeps the blank
// lines the source had, and no more.
BlankLineBeforeSection bool
}
Format tunes the encoding of the elements that have no source bytes to be written back from: the ones added or modified since the parsing.
It has no effect on the untouched elements, which are always written back verbatim.
type Key ¶
type Key struct {
// contains filtered or unexported fields
}
Key is a name/value pair in a section.
func (*Key) SetValue ¶
SetValue sets the key value and drops the source formatting of the key line, which is encoded again on write. The comments preceding the key are kept.
func (*Key) SetValueKeepFormat ¶
SetValueKeepFormat sets the key value by substituting it in the source text of the key line, so the key name, the spacing, the inline comment and the layout of a multiline value are all preserved. This is what a redaction needs: only the secret is replaced, the file is otherwise untouched.
It falls back to SetValue when the source text is unavailable, or when substituting would not parse back to value, and reports whether the formatting could be preserved.
type Options ¶
type Options struct {
// Loose does not error out when a source file does not exist.
Loose bool
// AllowPythonMultilineValues continues a value on the following
// lines when those lines begin with a space, a tab or a form feed.
AllowPythonMultilineValues bool
// SpaceBeforeInlineComment requires a whitespace before the '#' or
// ';' introducing an inline comment. Without it, any '#' or ';' in a
// value starts a comment.
SpaceBeforeInlineComment bool
// IgnoreInlineComment keeps the '#' and ';' markers and the text
// following them in the value.
IgnoreInlineComment bool
// IgnoreContinuation does not join a line ending with a backslash
// with the line that follows.
IgnoreContinuation bool
// KeyValueDelimiters lists the runes accepted as key/value separator
// on read. Defaults to "=:".
KeyValueDelimiters string
// ChildSectionDelimiter separates a child section name from its
// parent name. A key missing from a child section is looked up in
// its parent. Defaults to ".".
ChildSectionDelimiter string
// DefaultSectionName is the name of the section holding the keys
// defined before the first section header. Defaults to "DEFAULT".
DefaultSectionName string
}
Options tunes the accepted syntax.
type Section ¶
type Section struct {
// contains filtered or unexported fields
}
Section is a named group of keys.
func (*Section) GetKey ¶
GetKey returns the named key, or an error when it does not exist.
A key missing from a child section is looked up in its parent sections, the child section delimiter separating the names.
func (*Section) HasKey ¶
HasKey reports whether the section, or one of its parent sections, has the named key.
func (*Section) KeyStrings ¶
KeyStrings returns the section key names, in document order.