mirror of
https://github.com/octoleo/syncthing.git
synced 2024-11-09 23:00:58 +00:00
Remove deprected .ini format reader
This commit is contained in:
parent
8dee10ba9c
commit
ee0ee0e39d
4
Godeps/Godeps.json
generated
4
Godeps/Godeps.json
generated
@ -15,10 +15,6 @@
|
|||||||
"Comment": "null-81",
|
"Comment": "null-81",
|
||||||
"Rev": "9cbe983aed9b0dfc73954433fead5e00866342ac"
|
"Rev": "9cbe983aed9b0dfc73954433fead5e00866342ac"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"ImportPath": "github.com/calmh/ini",
|
|
||||||
"Rev": "386c4240a9684d91d9ec4d93651909b49c7269e1"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/codegangsta/inject",
|
"ImportPath": "github.com/codegangsta/inject",
|
||||||
"Rev": "9aea7a2fa5b79ef7fc00f63a575e72df33b4e886"
|
"Rev": "9aea7a2fa5b79ef7fc00f63a575e72df33b4e886"
|
||||||
|
19
Godeps/_workspace/src/github.com/calmh/ini/LICENSE
generated
vendored
19
Godeps/_workspace/src/github.com/calmh/ini/LICENSE
generated
vendored
@ -1,19 +0,0 @@
|
|||||||
Copyright (C) 2013 Jakob Borg
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
- The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
39
Godeps/_workspace/src/github.com/calmh/ini/README.md
generated
vendored
39
Godeps/_workspace/src/github.com/calmh/ini/README.md
generated
vendored
@ -1,39 +0,0 @@
|
|||||||
ini [![Build Status](https://drone.io/github.com/calmh/ini/status.png)](https://drone.io/github.com/calmh/ini/latest)
|
|
||||||
===
|
|
||||||
|
|
||||||
Yet another .INI file parser / writer. Created because the existing ones
|
|
||||||
were either not general enough (allowing easy access to all parts of the
|
|
||||||
original file) or made annoying assumptions about the format. And
|
|
||||||
probably equal parts NIH. You might want to just write your own instead
|
|
||||||
of using this one, you know that's where you'll end up in the end
|
|
||||||
anyhow.
|
|
||||||
|
|
||||||
Documentation
|
|
||||||
-------------
|
|
||||||
|
|
||||||
http://godoc.org/github.com/calmh/ini
|
|
||||||
|
|
||||||
Example
|
|
||||||
-------
|
|
||||||
|
|
||||||
```go
|
|
||||||
fd, _ := os.Open("foo.ini")
|
|
||||||
cfg := ini.Parse(fd)
|
|
||||||
fd.Close()
|
|
||||||
|
|
||||||
val := cfg.Get("general", "foo")
|
|
||||||
cfg.Set("general", "bar", "baz")
|
|
||||||
|
|
||||||
fd, _ = os.Create("bar.ini")
|
|
||||||
err := cfg.Write(fd)
|
|
||||||
if err != nil {
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
err = fd.Close()
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
License
|
|
||||||
-------
|
|
||||||
|
|
||||||
MIT
|
|
235
Godeps/_workspace/src/github.com/calmh/ini/ini.go
generated
vendored
235
Godeps/_workspace/src/github.com/calmh/ini/ini.go
generated
vendored
@ -1,235 +0,0 @@
|
|||||||
// Package ini provides trivial parsing of .INI format files.
|
|
||||||
package ini
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Config is a parsed INI format file.
|
|
||||||
type Config struct {
|
|
||||||
sections []section
|
|
||||||
comments []string
|
|
||||||
}
|
|
||||||
|
|
||||||
type section struct {
|
|
||||||
name string
|
|
||||||
comments []string
|
|
||||||
options []option
|
|
||||||
}
|
|
||||||
|
|
||||||
type option struct {
|
|
||||||
name, value string
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
iniSectionRe = regexp.MustCompile(`^\[(.+)\]$`)
|
|
||||||
iniOptionRe = regexp.MustCompile(`^([^\s=]+)\s*=\s*(.+?)$`)
|
|
||||||
)
|
|
||||||
|
|
||||||
// Sections returns the list of sections in the file.
|
|
||||||
func (c *Config) Sections() []string {
|
|
||||||
var sections []string
|
|
||||||
for _, sect := range c.sections {
|
|
||||||
sections = append(sections, sect.name)
|
|
||||||
}
|
|
||||||
return sections
|
|
||||||
}
|
|
||||||
|
|
||||||
// Options returns the list of options in a given section.
|
|
||||||
func (c *Config) Options(section string) []string {
|
|
||||||
var options []string
|
|
||||||
for _, sect := range c.sections {
|
|
||||||
if sect.name == section {
|
|
||||||
for _, opt := range sect.options {
|
|
||||||
options = append(options, opt.name)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return options
|
|
||||||
}
|
|
||||||
|
|
||||||
// OptionMap returns the map option => value for a given section.
|
|
||||||
func (c *Config) OptionMap(section string) map[string]string {
|
|
||||||
options := make(map[string]string)
|
|
||||||
for _, sect := range c.sections {
|
|
||||||
if sect.name == section {
|
|
||||||
for _, opt := range sect.options {
|
|
||||||
options[opt.name] = opt.value
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return options
|
|
||||||
}
|
|
||||||
|
|
||||||
// Comments returns the list of comments in a given section.
|
|
||||||
// For the empty string, returns the file comments.
|
|
||||||
func (c *Config) Comments(section string) []string {
|
|
||||||
if section == "" {
|
|
||||||
return c.comments
|
|
||||||
}
|
|
||||||
for _, sect := range c.sections {
|
|
||||||
if sect.name == section {
|
|
||||||
return sect.comments
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddComments appends the comment to the list of comments for the section.
|
|
||||||
func (c *Config) AddComment(sect, comment string) {
|
|
||||||
if sect == "" {
|
|
||||||
c.comments = append(c.comments, comment)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, s := range c.sections {
|
|
||||||
if s.name == sect {
|
|
||||||
c.sections[i].comments = append(s.comments, comment)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c.sections = append(c.sections, section{
|
|
||||||
name: sect,
|
|
||||||
comments: []string{comment},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse reads the given io.Reader and returns a parsed Config object.
|
|
||||||
func Parse(stream io.Reader) Config {
|
|
||||||
var cfg Config
|
|
||||||
var curSection string
|
|
||||||
|
|
||||||
scanner := bufio.NewScanner(bufio.NewReader(stream))
|
|
||||||
for scanner.Scan() {
|
|
||||||
line := strings.TrimSpace(scanner.Text())
|
|
||||||
if strings.HasPrefix(line, "#") || strings.HasPrefix(line, ";") {
|
|
||||||
comment := strings.TrimLeft(line, ";# ")
|
|
||||||
cfg.AddComment(curSection, comment)
|
|
||||||
} else if len(line) > 0 {
|
|
||||||
if m := iniSectionRe.FindStringSubmatch(line); len(m) > 0 {
|
|
||||||
curSection = m[1]
|
|
||||||
} else if m := iniOptionRe.FindStringSubmatch(line); len(m) > 0 {
|
|
||||||
key := m[1]
|
|
||||||
val := m[2]
|
|
||||||
if !strings.Contains(val, "\"") {
|
|
||||||
// If val does not contain any quote characers, we can make it
|
|
||||||
// a quoted string and safely let strconv.Unquote sort out any
|
|
||||||
// escapes
|
|
||||||
val = "\"" + val + "\""
|
|
||||||
}
|
|
||||||
if val[0] == '"' {
|
|
||||||
val, _ = strconv.Unquote(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg.Set(curSection, key, val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cfg
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write writes the sections and options to the io.Writer in INI format.
|
|
||||||
func (c *Config) Write(out io.Writer) error {
|
|
||||||
for _, cmt := range c.comments {
|
|
||||||
fmt.Fprintln(out, "; "+cmt)
|
|
||||||
}
|
|
||||||
if len(c.comments) > 0 {
|
|
||||||
fmt.Fprintln(out)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, sect := range c.sections {
|
|
||||||
fmt.Fprintf(out, "[%s]\n", sect.name)
|
|
||||||
for _, cmt := range sect.comments {
|
|
||||||
fmt.Fprintln(out, "; "+cmt)
|
|
||||||
}
|
|
||||||
for _, opt := range sect.options {
|
|
||||||
val := opt.value
|
|
||||||
if len(val) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quote the string if it begins or ends with space
|
|
||||||
needsQuoting := val[0] == ' ' || val[len(val)-1] == ' '
|
|
||||||
|
|
||||||
if !needsQuoting {
|
|
||||||
// Quote the string if it contains any unprintable characters
|
|
||||||
for _, r := range val {
|
|
||||||
if !strconv.IsPrint(r) {
|
|
||||||
needsQuoting = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if needsQuoting {
|
|
||||||
val = strconv.Quote(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Fprintf(out, "%s=%s\n", opt.name, val)
|
|
||||||
}
|
|
||||||
fmt.Fprintln(out)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get gets the value from the specified section and key name, or the empty
|
|
||||||
// string if either the section or the key is missing.
|
|
||||||
func (c *Config) Get(section, key string) string {
|
|
||||||
for _, sect := range c.sections {
|
|
||||||
if sect.name == section {
|
|
||||||
for _, opt := range sect.options {
|
|
||||||
if opt.name == key {
|
|
||||||
return opt.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set sets a value for an option in a section. If the option exists, it's
|
|
||||||
// value will be overwritten. If the option does not exist, it will be added.
|
|
||||||
// If the section does not exist, it will be added and the option added to it.
|
|
||||||
func (c *Config) Set(sectionName, key, value string) {
|
|
||||||
for i, sect := range c.sections {
|
|
||||||
if sect.name == sectionName {
|
|
||||||
for j, opt := range sect.options {
|
|
||||||
if opt.name == key {
|
|
||||||
c.sections[i].options[j].value = value
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.sections[i].options = append(sect.options, option{key, value})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c.sections = append(c.sections, section{
|
|
||||||
name: sectionName,
|
|
||||||
options: []option{{key, value}},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete removes the option from the specified section.
|
|
||||||
func (c *Config) Delete(section, key string) {
|
|
||||||
for sn, sect := range c.sections {
|
|
||||||
if sect.name == section {
|
|
||||||
for i, opt := range sect.options {
|
|
||||||
if opt.name == key {
|
|
||||||
c.sections[sn].options = append(sect.options[:i], sect.options[i+1:]...)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
214
Godeps/_workspace/src/github.com/calmh/ini/ini_test.go
generated
vendored
214
Godeps/_workspace/src/github.com/calmh/ini/ini_test.go
generated
vendored
@ -1,214 +0,0 @@
|
|||||||
package ini_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/calmh/ini"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestParseValues(t *testing.T) {
|
|
||||||
strs := []string{
|
|
||||||
`[general]`,
|
|
||||||
`k1=v1`,
|
|
||||||
`k2 = v2`,
|
|
||||||
` k3 = v3 `,
|
|
||||||
`k4=" quoted spaces "`,
|
|
||||||
`k5 = " quoted spaces " `,
|
|
||||||
`k6 = with\nnewline`,
|
|
||||||
`k7 = "with\nnewline"`,
|
|
||||||
`k8 = a "quoted" word`,
|
|
||||||
`k9 = "a \"quoted\" word"`,
|
|
||||||
}
|
|
||||||
buf := bytes.NewBufferString(strings.Join(strs, "\n"))
|
|
||||||
cfg := ini.Parse(buf)
|
|
||||||
|
|
||||||
correct := map[string]string{
|
|
||||||
"k1": "v1",
|
|
||||||
"k2": "v2",
|
|
||||||
"k3": "v3",
|
|
||||||
"k4": " quoted spaces ",
|
|
||||||
"k5": " quoted spaces ",
|
|
||||||
"k6": "with\nnewline",
|
|
||||||
"k7": "with\nnewline",
|
|
||||||
"k8": "a \"quoted\" word",
|
|
||||||
"k9": "a \"quoted\" word",
|
|
||||||
}
|
|
||||||
|
|
||||||
for k, v := range correct {
|
|
||||||
if v2 := cfg.Get("general", k); v2 != v {
|
|
||||||
t.Errorf("Incorrect general.%s, %q != %q", k, v2, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if v := cfg.Get("general", "nonexistant"); v != "" {
|
|
||||||
t.Errorf("Unexpected non-empty value %q", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestParseComments(t *testing.T) {
|
|
||||||
strs := []string{
|
|
||||||
";file comment 1", // No leading space
|
|
||||||
"; file comment 2 ", // Trailing space
|
|
||||||
"; file comment 3", // Multiple leading spaces
|
|
||||||
"[general]",
|
|
||||||
"; b general comment 1", // Comments in unsorted order
|
|
||||||
"somekey = somevalue",
|
|
||||||
"; a general comment 2",
|
|
||||||
"[other]",
|
|
||||||
"; other comment 1", // Comments in section with no values
|
|
||||||
"; other comment 2",
|
|
||||||
"[other2]",
|
|
||||||
"; other2 comment 1",
|
|
||||||
"; other2 comment 2", // Comments on last section
|
|
||||||
"somekey = somevalue",
|
|
||||||
}
|
|
||||||
buf := bytes.NewBufferString(strings.Join(strs, "\n"))
|
|
||||||
|
|
||||||
correct := map[string][]string{
|
|
||||||
"": []string{"file comment 1", "file comment 2", "file comment 3"},
|
|
||||||
"general": []string{"b general comment 1", "a general comment 2"},
|
|
||||||
"other": []string{"other comment 1", "other comment 2"},
|
|
||||||
"other2": []string{"other2 comment 1", "other2 comment 2"},
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg := ini.Parse(buf)
|
|
||||||
|
|
||||||
for section, comments := range correct {
|
|
||||||
cmts := cfg.Comments(section)
|
|
||||||
if len(cmts) != len(comments) {
|
|
||||||
t.Errorf("Incorrect number of comments for section %q: %d != %d", section, len(cmts), len(comments))
|
|
||||||
} else {
|
|
||||||
for i := range comments {
|
|
||||||
if cmts[i] != comments[i] {
|
|
||||||
t.Errorf("Incorrect comment: %q != %q", cmts[i], comments[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWrite(t *testing.T) {
|
|
||||||
cfg := ini.Config{}
|
|
||||||
cfg.Set("general", "k1", "v1")
|
|
||||||
cfg.Set("general", "k2", "foo bar")
|
|
||||||
cfg.Set("general", "k3", " foo bar ")
|
|
||||||
cfg.Set("general", "k4", "foo\nbar")
|
|
||||||
|
|
||||||
var out bytes.Buffer
|
|
||||||
cfg.Write(&out)
|
|
||||||
|
|
||||||
correct := `[general]
|
|
||||||
k1=v1
|
|
||||||
k2=foo bar
|
|
||||||
k3=" foo bar "
|
|
||||||
k4="foo\nbar"
|
|
||||||
|
|
||||||
`
|
|
||||||
if s := out.String(); s != correct {
|
|
||||||
t.Errorf("Incorrect written .INI:\n%s\ncorrect:\n%s", s, correct)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSet(t *testing.T) {
|
|
||||||
buf := bytes.NewBufferString("[general]\nfoo=bar\nfoo2=bar2\n")
|
|
||||||
cfg := ini.Parse(buf)
|
|
||||||
|
|
||||||
cfg.Set("general", "foo", "baz") // Overwrite existing
|
|
||||||
cfg.Set("general", "baz", "quux") // Create new value
|
|
||||||
cfg.Set("other", "baz2", "quux2") // Create new section + value
|
|
||||||
|
|
||||||
var out bytes.Buffer
|
|
||||||
cfg.Write(&out)
|
|
||||||
|
|
||||||
correct := `[general]
|
|
||||||
foo=baz
|
|
||||||
foo2=bar2
|
|
||||||
baz=quux
|
|
||||||
|
|
||||||
[other]
|
|
||||||
baz2=quux2
|
|
||||||
|
|
||||||
`
|
|
||||||
|
|
||||||
if s := out.String(); s != correct {
|
|
||||||
t.Errorf("Incorrect INI after set:\n%s", s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDelete(t *testing.T) {
|
|
||||||
buf := bytes.NewBufferString("[general]\nfoo=bar\nfoo2=bar2\nfoo3=baz\n")
|
|
||||||
cfg := ini.Parse(buf)
|
|
||||||
cfg.Delete("general", "foo")
|
|
||||||
out := new(bytes.Buffer)
|
|
||||||
cfg.Write(out)
|
|
||||||
correct := "[general]\nfoo2=bar2\nfoo3=baz\n\n"
|
|
||||||
|
|
||||||
if s := out.String(); s != correct {
|
|
||||||
t.Errorf("Incorrect INI after delete:\n%s", s)
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = bytes.NewBufferString("[general]\nfoo=bar\nfoo2=bar2\nfoo3=baz\n")
|
|
||||||
cfg = ini.Parse(buf)
|
|
||||||
cfg.Delete("general", "foo2")
|
|
||||||
out = new(bytes.Buffer)
|
|
||||||
cfg.Write(out)
|
|
||||||
correct = "[general]\nfoo=bar\nfoo3=baz\n\n"
|
|
||||||
|
|
||||||
if s := out.String(); s != correct {
|
|
||||||
t.Errorf("Incorrect INI after delete:\n%s", s)
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = bytes.NewBufferString("[general]\nfoo=bar\nfoo2=bar2\nfoo3=baz\n")
|
|
||||||
cfg = ini.Parse(buf)
|
|
||||||
cfg.Delete("general", "foo3")
|
|
||||||
out = new(bytes.Buffer)
|
|
||||||
cfg.Write(out)
|
|
||||||
correct = "[general]\nfoo=bar\nfoo2=bar2\n\n"
|
|
||||||
|
|
||||||
if s := out.String(); s != correct {
|
|
||||||
t.Errorf("Incorrect INI after delete:\n%s", s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSetManyEquals(t *testing.T) {
|
|
||||||
buf := bytes.NewBufferString("[general]\nfoo=bar==\nfoo2=bar2==\n")
|
|
||||||
cfg := ini.Parse(buf)
|
|
||||||
|
|
||||||
cfg.Set("general", "foo", "baz==")
|
|
||||||
|
|
||||||
var out bytes.Buffer
|
|
||||||
cfg.Write(&out)
|
|
||||||
|
|
||||||
correct := `[general]
|
|
||||||
foo=baz==
|
|
||||||
foo2=bar2==
|
|
||||||
|
|
||||||
`
|
|
||||||
|
|
||||||
if s := out.String(); s != correct {
|
|
||||||
t.Errorf("Incorrect INI after set:\n%s", s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRewriteDuplicate(t *testing.T) {
|
|
||||||
buf := bytes.NewBufferString("[general]\nfoo=bar==\nfoo=bar2==\n")
|
|
||||||
cfg := ini.Parse(buf)
|
|
||||||
|
|
||||||
if v := cfg.Get("general", "foo"); v != "bar2==" {
|
|
||||||
t.Errorf("incorrect get %q", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
var out bytes.Buffer
|
|
||||||
cfg.Write(&out)
|
|
||||||
|
|
||||||
correct := `[general]
|
|
||||||
foo=bar2==
|
|
||||||
|
|
||||||
`
|
|
||||||
|
|
||||||
if s := out.String(); s != correct {
|
|
||||||
t.Errorf("Incorrect INI after set:\n%s", s)
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,7 +8,6 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Configuration struct {
|
type Configuration struct {
|
||||||
@ -107,41 +106,6 @@ func fillNilSlices(data interface{}) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func readConfigINI(m map[string]string, data interface{}) error {
|
|
||||||
s := reflect.ValueOf(data).Elem()
|
|
||||||
t := s.Type()
|
|
||||||
|
|
||||||
for i := 0; i < s.NumField(); i++ {
|
|
||||||
f := s.Field(i)
|
|
||||||
tag := t.Field(i).Tag
|
|
||||||
|
|
||||||
name := tag.Get("ini")
|
|
||||||
if len(name) == 0 {
|
|
||||||
name = strings.ToLower(t.Field(i).Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := m[name]; ok {
|
|
||||||
switch f.Interface().(type) {
|
|
||||||
case string:
|
|
||||||
f.SetString(v)
|
|
||||||
|
|
||||||
case int:
|
|
||||||
i, err := strconv.ParseInt(v, 10, 64)
|
|
||||||
if err == nil {
|
|
||||||
f.SetInt(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
case bool:
|
|
||||||
f.SetBool(v == "true")
|
|
||||||
|
|
||||||
default:
|
|
||||||
panic(f.Type())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func writeConfigXML(wr io.Writer, cfg Configuration) error {
|
func writeConfigXML(wr io.Writer, cfg Configuration) error {
|
||||||
e := xml.NewEncoder(wr)
|
e := xml.NewEncoder(wr)
|
||||||
e.Indent("", " ")
|
e.Indent("", " ")
|
||||||
|
@ -16,8 +16,6 @@ import (
|
|||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/calmh/ini"
|
|
||||||
"github.com/calmh/syncthing/discover"
|
"github.com/calmh/syncthing/discover"
|
||||||
"github.com/calmh/syncthing/protocol"
|
"github.com/calmh/syncthing/protocol"
|
||||||
"github.com/juju/ratelimit"
|
"github.com/juju/ratelimit"
|
||||||
@ -120,31 +118,6 @@ func main() {
|
|||||||
fatalln(err)
|
fatalln(err)
|
||||||
}
|
}
|
||||||
cf.Close()
|
cf.Close()
|
||||||
} else {
|
|
||||||
// No config.xml, let's try the old syncthing.ini
|
|
||||||
iniFile := filepath.Join(confDir, "syncthing.ini")
|
|
||||||
cf, err := os.Open(iniFile)
|
|
||||||
if err == nil {
|
|
||||||
infoln("Migrating syncthing.ini to config.xml")
|
|
||||||
iniCfg := ini.Parse(cf)
|
|
||||||
cf.Close()
|
|
||||||
Rename(iniFile, filepath.Join(confDir, "migrated_syncthing.ini"))
|
|
||||||
|
|
||||||
cfg, _ = readConfigXML(nil)
|
|
||||||
cfg.Repositories = []RepositoryConfiguration{
|
|
||||||
{Directory: iniCfg.Get("repository", "dir")},
|
|
||||||
}
|
|
||||||
readConfigINI(iniCfg.OptionMap("settings"), &cfg.Options)
|
|
||||||
for name, addrs := range iniCfg.OptionMap("nodes") {
|
|
||||||
n := NodeConfiguration{
|
|
||||||
NodeID: name,
|
|
||||||
Addresses: strings.Fields(addrs),
|
|
||||||
}
|
|
||||||
cfg.Repositories[0].Nodes = append(cfg.Repositories[0].Nodes, n)
|
|
||||||
}
|
|
||||||
|
|
||||||
saveConfig()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(cfg.Repositories) == 0 {
|
if len(cfg.Repositories) == 0 {
|
||||||
|
Loading…
Reference in New Issue
Block a user