1package config 2 3import ( 4 "fmt" 5 "io" 6 "strings" 7) 8 9// An Encoder writes config files to an output stream. 10type Encoder struct { 11 w io.Writer 12} 13 14// NewEncoder returns a new encoder that writes to w. 15func NewEncoder(w io.Writer) *Encoder { 16 return &Encoder{w} 17} 18 19// Encode writes the config in git config format to the stream of the encoder. 20func (e *Encoder) Encode(cfg *Config) error { 21 for _, s := range cfg.Sections { 22 if err := e.encodeSection(s); err != nil { 23 return err 24 } 25 } 26 27 return nil 28} 29 30func (e *Encoder) encodeSection(s *Section) error { 31 if len(s.Options) > 0 { 32 if err := e.printf("[%s]\n", s.Name); err != nil { 33 return err 34 } 35 36 if err := e.encodeOptions(s.Options); err != nil { 37 return err 38 } 39 } 40 41 for _, ss := range s.Subsections { 42 if err := e.encodeSubsection(s.Name, ss); err != nil { 43 return err 44 } 45 } 46 47 return nil 48} 49 50func (e *Encoder) encodeSubsection(sectionName string, s *Subsection) error { 51 //TODO: escape 52 if err := e.printf("[%s \"%s\"]\n", sectionName, s.Name); err != nil { 53 return err 54 } 55 56 if err := e.encodeOptions(s.Options); err != nil { 57 return err 58 } 59 60 return nil 61} 62 63func (e *Encoder) encodeOptions(opts Options) error { 64 for _, o := range opts { 65 pattern := "\t%s = %s\n" 66 if strings.Index(o.Value, "\\") != -1 { 67 pattern = "\t%s = %q\n" 68 } 69 70 if err := e.printf(pattern, o.Key, o.Value); err != nil { 71 return err 72 } 73 } 74 75 return nil 76} 77 78func (e *Encoder) printf(msg string, args ...interface{}) error { 79 _, err := fmt.Fprintf(e.w, msg, args...) 80 return err 81} 82