inifiles

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 20, 2026 License: MIT Imports: 10 Imported by: 0

README

inifiles

Go Reference

A Go port of the Perl Config::IniFiles module for reading and writing .ini-style configuration files.

The goal is behavioral parity: the same INI dialect is accepted/produced and the same round-trip-preservation guarantees hold, with an idiomatic Go API.

Features ported

  • Sections ([name]), parameters (key=value), comments (#/;)
  • Multi-line / here-doc values (parm=<<EOT … EOT), with collision-safe EOT marker selection
  • Backslash line continuation (-allowcontinue)
  • Trailing (end-of-line) comments (-handle_trailing_comment)
  • Verbatim comment, blank-line-on-write, and ordering preservation
  • Line-ending detection and round-trip (\n, \r, \r\n, \x15)
  • UTF-8 BOM stripping on the first line
  • Case-insensitive mode (-nocase)
  • -default section fallback and -fallback section for loose keys
  • -import overlay/shadowing with delta output (-delta)
  • Negative deltas (; [sect] is deleted / ; parm is deleted)
  • -nomultiline output, -php_compat, -allowempty
  • Groups derived from section names (Group Section Member)
  • Atomic file writes (temp file + rename) honoring the recorded file mode
  • Refusal to write to a read-only destination

Quick start

import "github.com/inverse-inc/go-config-inifiles"

cfg, err := inifiles.NewFromFile("config.ini")
if err != nil { log.Fatal(err) }

v, ok := cfg.Val("Section", "Parameter")          // joined with "\n" if multi-line
lines, _ := cfg.Vals("Section", "Mult")            // []string

cfg.NewVal("Section", "New", "value")
if err := cfg.WriteFile("config.ini"); err != nil { log.Fatal(err) }

Constructors: NewFromFile(path, opts...), NewFromReader(r, opts...), NewFromBytes(b, opts...), New(opts...).

Options (functional)

WithDefault, WithFallback, WithNoCase, WithNoMultiline, WithAllowContinue, WithAllowEmpty, WithNegativeDeltas, WithCommentChar, WithAllowedCommentChars, WithTrailingComment, WithPHPCompat, WithImport, WithReloadWarn.

API notes (Perl → Go)

This port replaces Perl-only constructs with idiomatic Go:

  • The tied-hash interface ($cfg{Section}{param}) is exposed as explicit methods: Sections, Parameters, Val/Vals, NewVal/SetVal/ PushVal/DelVal, AddSection/DeleteSection/RenameSection/ CopySection, etc.
  • wantarray dual-context val() becomes Val (scalar, joined with \n) and Vals (slice).
  • Errors use returned errors; accumulated parse errors are available via Config.Errors() []ParseError.
  • -file accepts an io.Reader, string path, or *os.File; in-memory configs use NewFromBytes.

Dropped / approximated Perl behaviors

  • Taint mode (Perl -T) has no Go equivalent; the taint-only assertions of tests 17 are dropped. (Their non-taint assertions are covered elsewhere.)
  • OutputConfig() (writing to Perl's globally-selected filehandle) has no Go equivalent; use WriteTo(io.Writer).
  • -allowedcommentchars is interpreted as a set of runes (printed, non-alphanumeric, non-[]:=) rather than a raw regex character-class body — identical observable behavior for all documented inputs.
  • Array-context assignment ($ini{s} = @arr assigning the element count) has no Go equivalent and is not reproduced.

Testing

The Perl test suite (config-inifiles/t/*.t) has been translated to Go table tests. Run:

go test ./...
go test -cover ./...

Test fixtures live under testdata/ (copied verbatim from the Perl distribution).

License

MIT, derived from the Perl Config::IniFiles distribution. See LICENSE.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrAlreadyExists = errors.New("inifiles: section already exists")

ErrAlreadyExists is returned when a creation operation targets a section or parameter that already exists.

View Source
var ErrEmptyArg = errors.New("inifiles: empty section or parameter name")

ErrEmptyArg is returned when a section, parameter, or other required argument is the empty string.

View Source
var ErrNotFound = errors.New("inifiles: section or parameter not found")

ErrNotFound is returned when a section or parameter does not exist.

Functions

This section is empty.

Types

type Config

type Config struct {
	// contains filtered or unexported fields
}

Config is a parsed .ini configuration, ported from Perl's Config::IniFiles. Use New, NewFromFile, NewFromReader, or NewFromBytes to create one.

func New

func New(opts ...Option) *Config

New creates an empty Config without reading any file. Equivalent to Perl new() with no -file. Options may include WithFileName via... (use SetFileName after) -- callers pass opts for nocase/comment/etc.

func NewFromBytes

func NewFromBytes(b []byte, opts ...Option) (*Config, error)

NewFromBytes creates a Config from an in-memory byte slice. Convenience over NewFromReader(bytes.NewReader(b)).

func NewFromFile

func NewFromFile(path string, opts ...Option) (*Config, error)

NewFromFile creates a Config by reading the file at path.

func NewFromReader

func NewFromReader(r interface{ Read([]byte) (int, error) }, opts ...Option) (*Config, error)

NewFromReader creates a Config by reading from r. No file path is recorded, so WriteFile will require SetFileName first. The detected line ending (if any) is reused for subsequent writes. r is consumed entirely.

func (*Config) AddSection

func (c *Config) AddSection(sect string) error

AddSection creates a section if it does not already exist. It is idempotent: re-adding an existing section is a no-op (returns nil). An empty sect returns ErrEmptyArg.

func (*Config) CopySection

func (c *Config) CopySection(old, newName string, includeGroup bool) error

CopySection copies old into newName (no overwrite). When includeGroup is true, group members of old are recursively copied to counterparts with the name prefix replaced; existing counterparts are skipped and the rest of the group is still copied. An empty old or newName returns ErrEmptyArg. A missing old section returns ErrNotFound. An existing destination returns ErrAlreadyExists.

func (*Config) DelVal

func (c *Config) DelVal(sect, parm string) error

DelVal deletes sect.parm, recording a tombstone for delta output. Deleting a missing section or parameter is a no-op (returns nil). An empty sect or parm returns ErrEmptyArg.

func (*Config) Delete

func (c *Config) Delete()

Delete removes every section from the configuration.

func (*Config) DeleteParameterComment

func (c *Config) DeleteParameterComment(sect, parm string) error

DeleteParameterComment removes sect.parm's comment lines. Deleting the comment on a missing parameter is a no-op (returns nil). An empty sect or parm returns ErrEmptyArg.

func (*Config) DeleteParameterEOT

func (c *Config) DeleteParameterEOT(sect, parm string) error

DeleteParameterEOT removes the here-doc terminator marker from the parameter. A multi-valued param reverts to the default "EOT" marker on output. Deleting the marker on a missing parameter is a no-op (returns nil). An empty sect or parm returns ErrEmptyArg.

func (*Config) DeleteSection

func (c *Config) DeleteSection(sect string) error

DeleteSection removes sect and all its parameters, recording a tombstone for delta output. Deleting a missing section is a no-op (returns nil). An empty sect returns ErrEmptyArg.

func (*Config) DeleteSectionComment

func (c *Config) DeleteSectionComment(sect string) error

DeleteSectionComment removes the comment lines above sect. Deleting the comment on a missing section is a no-op (returns nil). An empty sect returns ErrEmptyArg.

func (*Config) Errors

func (c *Config) Errors() []ParseError

Errors returns the errors accumulated during the most recent read.

func (*Config) Exists

func (c *Config) Exists(sect, parm string) bool

Exists reports whether sect.parm is present, ignoring the default section.

func (*Config) GetFileName

func (c *Config) GetFileName() string

GetFileName returns the configured file path (may be "").

func (*Config) GetParameterComment

func (c *Config) GetParameterComment(sect, parm string) ([]string, bool)

GetParameterComment returns sect.parm's comment lines, or nil,false if absent.

func (*Config) GetParameterEOT

func (c *Config) GetParameterEOT(sect, parm string) string

GetParameterEOT returns the here-doc terminator marker for the parameter, or "" if none was set. A multi-valued param auto-created without an explicit marker returns "EOT" (the default), mirroring Perl.

func (*Config) GetParameterTrailingComment

func (c *Config) GetParameterTrailingComment(sect, parm string) (string, bool)

GetParameterTrailingComment returns the end-of-line comment for sect.parm, or "" if none. The boolean reports whether the parameter exists.

func (*Config) GetSectionComment

func (c *Config) GetSectionComment(sect string) ([]string, bool)

GetSectionComment returns the section's comment lines (verbatim, prefixed as read). Returns nil,false if the section or its comment is absent.

func (*Config) GetWriteMode

func (c *Config) GetWriteMode() os.FileMode

GetWriteMode returns the configured file mode (permission bits only), or 0 if none has been set.

func (*Config) GroupMembers

func (c *Config) GroupMembers(group string) []string

GroupMembers returns the section names belonging to group, or nil if group is unknown.

func (*Config) Groups

func (c *Config) Groups() []string

Groups returns the names of all groups derived from section names.

func (*Config) IsImported

func (c *Config) IsImported(sect, parm string) bool

IsImported reports whether sect.parm originates from the imported config (i.e., the section is imported and the parameter has not been locally modified).

func (*Config) MyParameters

func (c *Config) MyParameters(sect string) []string

MyParameters returns the ordered parameter names of sect that are either in a non-imported section or have been modified (touched).

func (*Config) NewVal

func (c *Config) NewVal(sect, parm string, vals ...string) error

NewVal creates sect.parm with the given values, creating the section if needed. If multiple values are given the parameter is multi-valued (here-doc on output). An empty sect or parm returns ErrEmptyArg.

func (*Config) Parameters

func (c *Config) Parameters(sect string) []string

Parameters returns the ordered parameter names of sect (including imported).

func (*Config) PushVal

func (c *Config) PushVal(sect, parm string, vals ...string) error

PushVal appends values to an existing multi-valued (or scalar -> array) parameter. Returns ErrNotFound if the parameter does not exist. An empty sect or parm returns ErrEmptyArg. Passing no values is a no-op.

func (*Config) Reload

func (c *Config) Reload() error

Reload re-reads the configured file (if any), discarding in-memory changes. Mirrors Perl's ReadConfig.

func (*Config) RemoveGroupMember

func (c *Config) RemoveGroupMember(sect string)

RemoveGroupMember removes sect from its derived group (if any).

func (*Config) RenameSection

func (c *Config) RenameSection(old, newName string, includeGroup bool) error

RenameSection copies old to new and then deletes old.

func (*Config) ResortSections

func (c *Config) ResortSections(sects []string) error

ResortSections reorders the given sections into the supplied order, keeping every section not listed at its relative position around the reordered block (mirrors Perl Config::IniFiles::ResortSections). Every name in sects must refer to an existing section; otherwise ResortSections returns ErrNotFound and leaves the order untouched. An empty sects list (or a single-element list) is a no-op.

func (*Config) Rewrite

func (c *Config) Rewrite() error

Rewrite rewrites the configured file (mirrors Perl RewriteConfig).

func (*Config) SectionExists

func (c *Config) SectionExists(sect string) bool

SectionExists reports whether a section named sect is present.

func (*Config) Sections

func (c *Config) Sections() []string

Sections returns the ordered list of section names (including imported ones).

func (*Config) SetFileName

func (c *Config) SetFileName(name string) error

SetFileName sets the path used by Reload and Rewrite. An empty name returns ErrEmptyArg.

func (*Config) SetGroupMember

func (c *Config) SetGroupMember(sect string)

SetGroupMember enrolls sect in the group derived from its name (the first whitespace-delimited word, when the name contains a second word). This is invoked automatically by AddSection.

func (*Config) SetParameterComment

func (c *Config) SetParameterComment(sect, parm string, comments ...string) (int, error)

SetParameterComment sets the comment lines appearing above sect.parm, prefixing any line lacking an allowed comment leader. Returns the count of comment lines. An empty sect or parm returns ErrEmptyArg. Passing no comments is a no-op (0, nil).

func (*Config) SetParameterEOT

func (c *Config) SetParameterEOT(sect, parm, eot string) error

SetParameterEOT sets the here-doc terminator marker for the parameter. Once set, the parameter serializes as a here-doc block on write. An empty sect, parm, or eot returns ErrEmptyArg. A missing parameter returns ErrNotFound.

func (*Config) SetParameterTrailingComment

func (c *Config) SetParameterTrailingComment(sect, parm, cmt string) error

SetParameterTrailingComment sets the end-of-line comment for sect.parm. The parameter must exist; a missing parameter returns ErrNotFound. An empty sect or parm returns ErrEmptyArg. An empty cmt is a no-op (returns nil).

func (*Config) SetSectionComment

func (c *Config) SetSectionComment(sect string, comments ...string) (int, error)

SetSectionComment sets the comment lines appearing above sect, prefixing any line that lacks an allowed comment leader with "<commentChar> ". The section is created if it does not exist. Returns the count of comment lines. An empty sect returns ErrEmptyArg. Passing no comments is a no-op (0, nil).

func (*Config) SetVal

func (c *Config) SetVal(sect, parm string, vals ...string) error

SetVal sets an existing parameter's value(s). Returns ErrNotFound if the parameter does not already exist (use NewVal to create). An empty sect or parm returns ErrEmptyArg.

func (*Config) SetWriteMode

func (c *Config) SetWriteMode(mode os.FileMode)

SetWriteMode sets the file mode applied on WriteFile (only the permission bits are used). Pass 0 to clear the recorded mode.

func (*Config) Val

func (c *Config) Val(sect, parm string) (string, bool)

Val returns the value of sect.parm joined with newlines if multi-valued. The boolean reports whether the parameter (or a default-section fallback) was found.

func (*Config) ValWithDefault

func (c *Config) ValWithDefault(sect, parm, def string) string

ValWithDefault returns the value of sect.parm, or def when not found (mirrors Perl val's third argument default).

func (*Config) Vals

func (c *Config) Vals(sect, parm string) ([]string, bool)

Vals returns the value of sect.parm as a slice (one element for scalar values, multiple for here-doc/accumulated). The boolean reports whether the parameter (or a default-section fallback) was found. A missing parameter returns nil, false (mirrors Perl list-context val returning an empty list).

func (*Config) WriteFile

func (c *Config) WriteFile(path string) error

WriteFile writes the configuration to path atomically (temp file + rename) and applies the recorded file mode.

func (*Config) WriteFileDelta

func (c *Config) WriteFileDelta(path string) error

WriteFileDelta writes a delta file to path atomically.

func (*Config) WriteTo

func (c *Config) WriteTo(w io.Writer) (int64, error)

WriteTo writes the configuration to w using the detected line ending (or "\n" when none). It returns the number of bytes written.

func (*Config) WriteToDelta

func (c *Config) WriteToDelta(w io.Writer) (int64, error)

WriteToDelta writes only sections/parameters touched locally (plus deletion tombstones), producing a delta file suitable for re-applying atop an import.

type Option

type Option func(*Options)

Option configures Options.

func WithAllowContinue

func WithAllowContinue(b bool) Option

WithAllowContinue controls whether a trailing backslash acts as a line-continuation marker on read.

func WithAllowEmpty

func WithAllowEmpty(b bool) Option

WithAllowEmpty controls whether an empty config file is accepted or treated as an error.

func WithAllowedCommentChars

func WithAllowedCommentChars(rs []rune) Option

WithAllowedCommentChars sets extra runes recognized as comment leaders in addition to CommentChar.

func WithCommentChar

func WithCommentChar(r rune) Option

WithCommentChar sets the primary comment character used to prefix synthetic comment lines. Must be a single non-alphanumeric, non-[]:= rune.

func WithDefault

func WithDefault(name string) Option

WithDefault sets the section name consulted by Val when a parameter is missing in the requested section.

func WithFallback

func WithFallback(name string) Option

WithFallback sets the section into which parameters appearing before any section header are filed.

func WithImport

func WithImport(c *Config) Option

WithImport sets an existing *Config whose data is deep-copied as a base before reading the local file; local values shadow imported ones.

func WithNegativeDeltas

func WithNegativeDeltas(b bool) Option

WithNegativeDeltas controls whether "; [sect] is deleted" / "; parm is deleted" comments trigger deletions during read.

func WithNoCase

func WithNoCase(b bool) Option

WithNoCase controls case-insensitive section and parameter key matching.

func WithNoMultiline

func WithNoMultiline(b bool) Option

WithNoMultiline controls whether multi-valued parameters are serialized as repeated single lines instead of here-doc blocks.

func WithPHPCompat

func WithPHPCompat(b bool) Option

WithPHPCompat controls PHP-style "name[]" array-stripping and quote unwrapping on read.

func WithReloadWarn

func WithReloadWarn(b bool) Option

WithReloadWarn controls whether a reload notice is printed on each Reload after the first.

func WithReloadWriter

func WithReloadWriter(w *os.File) Option

WithReloadWriter sets the *os.File that receives reload warning messages. Defaults to os.Stderr.

func WithTrailingComment

func WithTrailingComment(b bool) Option

WithTrailingComment controls whether "value ; comment" is parsed into a value plus a trailing comment slot.

type Options

type Options struct {
	// Import is an existing *Config whose data is deep-copied as a base
	// before reading the local file (local values shadow imported ones).
	Import *Config

	// Default is the section name consulted by Val when a parameter is
	// missing in the requested section.
	Default string

	// Fallback is the section into which parameters appearing before any
	// section header are filed. Without it, such parameters are a parse
	// error. The fallback section header is suppressed on write when used.
	Fallback string

	// NoCase lowercases section and parameter keys (values keep original
	// case).
	NoCase bool

	// ReloadWarn prints a reload notice to ReloadWriter (default os.Stderr)
	// on each Reload after the first.
	ReloadWarn bool

	// NoMultiline outputs multi-valued parameters as repeated single lines
	// instead of here-doc blocks. Affects output only.
	NoMultiline bool

	// AllowContinue honors a trailing backslash as a line-continuation
	// marker on read.
	AllowContinue bool

	// AllowEmpty permits empty config files; otherwise they are an error.
	AllowEmpty bool

	// NegativeDeltas parses "; [sect] is deleted" / "; parm is deleted"
	// comments as deletions during read. Auto-enabled when Import is set.
	NegativeDeltas bool

	// CommentChar is the primary comment character used to prefix synthetic
	// comment lines. Must be a single non-alphanumeric, non-[]:= rune.
	CommentChar rune

	// AllowedCommentChars are extra runes recognized as comment leaders in
	// addition to CommentChar. Each must be printable and not alphanumeric
	// or one of [ ] : =.
	AllowedCommentChars []rune

	// HandleTrailingComment parses "value ; comment" into value plus a
	// trailing comment slot.
	HandleTrailingComment bool

	// PHPCompat strips trailing "[]" from parameter names and unwraps
	// quotes from values on read.
	PHPCompat bool

	// ReloadWriter receives the reload warning message when ReloadWarn is
	// true. Defaults to os.Stderr.
	ReloadWriter *os.File
	// contains filtered or unexported fields
}

Options controls parsing and writing behavior, mirroring the Perl Config::IniFiles constructor flags.

type ParseError

type ParseError struct {
	Line    int
	Message string
	Context string
}

ParseError describes an error encountered while reading a config.

func (*ParseError) Error

func (e *ParseError) Error() string

Error returns the error string, including the line number when available.

func (*ParseError) Unwrap

func (e *ParseError) Unwrap() error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL