Code Monkey home page Code Monkey logo

ini's People

Contributors

aligator avatar aronlt avatar ata18 avatar carterjones avatar decafjoe avatar drakkan avatar gandarez avatar greut avatar haroldht avatar jmluang avatar kuuyee avatar lispking avatar lyobzik avatar mkozjak avatar mswdevsla avatar ndagestad avatar nextrevision avatar peter-vaczi avatar pixdigit avatar r3db34n avatar radeksimko avatar ravron avatar ryaka avatar sagikazarmark avatar shahms avatar shawnps avatar syndbg avatar unknwon avatar yangkian avatar ygj6 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ini's Issues

Using MapTo

I'm pretty sure this isn't the right place to be asking for help but I'm not sure who else the experts would be :)

I'm tying to map cfg to a struct called Config in the code below. I do this but when I go to print conf it always shows up with empty and false values.

type Config struct {
    host string
    port int
}

func main () {
    cfg, err := ini.Load("/my/file.cfg")
    conf := new(Config)
    err = cfg.MapTo(conf)
    fmt.Println(conf)

When I run this I get
&{ 0}

If I use: cfg.Section("").Key("host")
I can get access to the Value for "host"

Am I trying to use MapTo incorrectly?

Sections should work with maps, maybe.

I understand maps (say, map[string]interface{}) are currently not supported to automagically translate to sections.

I have two questions:

  1. Have you considered it?
  2. Do you find it a great idea?
  3. If you do, do you intend to add support to this or are open to pull requests on this?

I have taken a quick look at setWithProperType and reflectWithProperType and it seems not to be so hard to do so, so maybe there is a good reason why it wasn't done on the first place (maybe because there were priorities and the delimiter didn't make it trivial?).

  • not that it is difficult to workaround this situation right now as you can just add it later like that:
cfg.Section("remotes").KeyHashs()

btw, I love the simplicity of this library. Well done! Keep up the good work!

Desired behavior when creating a new ini file

When using ini.load() to read a file that doesn't exist, you can proceed to use the returned object to make changes and ultimately persist the object to disk via SaveTo, however it looses the top level section. I fixed the issue in my program by making sure the ini file was initialized as an empty file (if missing) prior to loading, but I wondered what the intended behavior is in this case.

Here's an example program to illustrate the question:

package main

import (
    "fmt"
    "gopkg.in/ini.v1"
)

func main() {
    p := "/tmp/missing-file.ini"
    cfg, err := ini.Load(p)
    fmt.Println(cfg, err)
    cfg.Section("section").NewKey("key", "value")
    cfg.SaveTo(p)
}

Running the program results in this:

$ go run test.go
&{true {{0 0} 0 0 0 0} [{/tmp/missing-file.ini}] map[] [] <nil>} open /tmp/missing-file.ini: no such file or directory
$ cat /tmp/missing-file.ini
key = value

Because the write ultimately succeeded, running the same program again
has this result:

$ go run test.go
&{true {{0 0} 0 0 0 0} [{/tmp/missing-file.ini}] map[DEFAULT:0xc820018190] [DEFAULT] <nil>} <nil>
$ cat /tmp/missing-file.ini
key = value

[section]
key = value

Any thoughts on if this is the intended behavior? My instinct is that this is a defect, and the library should either write the correct textual representation of the object, or it should fail to write because the file doesn't exist (consistent with err returned by ini.load()).

Quoted strings cause issues

Consider the following:

key1 = "value" ; comment
key2 = "one", "two", "three"

When saved these get mangled to:

key1 = """"value" ; comment"""
key2 = """"one", "two", "three""""

Clearly not ideal!

Looking at the parsing code, I think you could really do with specifying a formal grammar. Here is an example.

Please add support for UTF16LE and UTF16BE

Many ini files for Windows are using UTF16LE (Little Endian) instead of UTF8. Rarely there are even UTF16 (Big Endian) files. The Windows API calls like GetPrivateProfileString will handle all of these formats automatically. All varieties UTF8, UTF16LE and UTF16BE will have a byte order mark (BOM) at the beginning. The BOM will guide you how to convert the byte content of the file to UTF8 (go string):

UTF-8: EF BB BF (first three bytes of file)
UTF16LE: FF FE (first two bytes of the file)
UTF16BE: FE FF (first two bytes of the file)

For testing you can use "Save as" of Windows Notepad. There you will find UTF8, Unicode (UTF16LE) and Unicode Big Endian (UTF16BE) format.

Support other boolean values

Currently, library support "true or false" for boolean values. It is a good idea to extend the support for "yes or no" and "on or off" values

Case insensitive ini keys

Please support case insensitive keys and sections in an ini file, ex: via an option.
ex: treat "FOO = bar" like "foo = bar" or "Foo = bar".
Thanks

Ignoring continuation character

I use go-ini for reading .ini files of a Windows application. Unfortunately the developer of that application decided to store pathnames with trailing backslashes:

[Directories]
SourceDir=C:\App\Source\
TargetDir=C:\App\Target\

When I read SourceDir I receive the value C:\App\SourceTargetDir=C:\App\Target\ because the \ gets treated as a continuation char.
Is it possible to tell the library not to handle the continuation char ? Unfortunately I can not change the ini files content because this breaks the application (which was not written by me and can not be changed by me)

Attempts to assign time.Duration to uint32 fields when value is 0

The following code panics when the value of the uint32 field is 0:

package main

import (
    "log"

    "github.com/go-ini/ini"
)

var iniOK = []byte(`string = string
uint32 = 1
`)
var iniBad = []byte(`string = string
uint32 = 0
`)

type myStruct struct {
    String string `ini:"string"`
    UInt32 uint32 `ini:"uint32"`
}

func main() {
    cfg, err := ini.Load(iniOK)
    if err != nil {
        log.Fatalf("Failed to load ini: %s", err)
    }
    my := &myStruct{}
    if err = cfg.Section("").MapTo(my); err != nil {
        log.Fatalf("Failed to map: %s", err)
    }
    log.Printf("UInt32 value = %d", my.UInt32)

    cfg, err = ini.Load(iniBad)
    if err != nil {
        log.Fatalf("Failed to load ini: %s", err)
    }
    my = &myStruct{}
    if err = cfg.Section("").MapTo(my); err != nil {
        log.Fatalf("Failed to map: %s", err)
    }
    log.Printf("UInt32 value = %d", my.UInt32)
}

Output:

2016/08/11 15:27:10 UInt32 value = 1
panic: reflect.Set: value of type time.Duration is not assignable to type uint32

goroutine 1 [running]:
panic(0x510780, 0xc82000a5b0)
        /usr/local/go/src/runtime/panic.go:481 +0x3e6
reflect.Value.assignTo(0x556000, 0xc82000a5a0, 0x86, 0x578af0, 0xb, 0x510900, 0x0, 0x0, 0x0, 0x0)
        /usr/local/go/src/reflect/value.go:2164 +0x3be
reflect.Value.Set(0x510900, 0xc82000e6d0, 0x18a, 0x556000, 0xc82000a5a0, 0x86)
        /usr/local/go/src/reflect/value.go:1334 +0x95
github.com/go-ini/ini.setWithProperType(0x7f9148f480a8, 0x510900, 0xc820010480, 0x510900, 0xc82000e6d0, 0x18a, 0x570c28, 0x1, 0x0, 0x0)
        /home/hhecker/go/src/github.com/go-ini/ini/struct.go:166 +0x651
github.com/go-ini/ini.(*Section).mapTo(0xc820012280, 0x547660, 0xc82000e6c0, 0x199, 0x0, 0x0)
        /home/hhecker/go/src/github.com/go-ini/ini/struct.go:232 +0x57c
github.com/go-ini/ini.(*Section).MapTo(0xc820012280, 0x502420, 0xc82000e6c0, 0x0, 0x0)
        /home/hhecker/go/src/github.com/go-ini/ini/struct.go:251 +0x1d7
main.main()
        /home/hhecker/ini-uint32-not-time.go:37 +0x569
exit status 2

Key value indention

Have not found anything so this probably is a feature request.

Is there a way to indent the key values pairs with some whitespaces? git for example uses an ini format like this:

[user]
        name = udondan
        email = [email protected]

[other section]
        foo = bar

ini can read this data but when writing it back it removes all the whitespaces. It would be great if there was an option to preserve whitespaces (detect when reading and write it back the same way) and/or define the desired number of spaces for the whole document.

中文文档里面,这种写法对吗?

获取分区下的所有键或键名:

keys := cfg.Section().Keys()
names := cfg.Section().KeyStrings()

前面一直都是cfg.Section(“”),这里的Section()不放参数真的可以吗?
新手勿怪!

Cannot update config file on Windows after v1 branch merge

go-ini is broken on Windows after the v1 branch merge, as it is no longer able to update its configuration file. Calls to SaveTo() fail with a message similar to:

ERROR Unable to update config file C:\Users\David.shipped\shipped.ini with apiToken=RLUtmYgmSVYBADDvoxIfsfgPyCKmxIub: rename C:\Users\David.shipped
shipped.ini.555854800.tmp C:\Users\David.shipped\shipped.ini: Cannot create a file when that file already exists.

The problem is in the new code that writes the update into a temporary file and then attempts to remove the old file and rename the new. In Windows, you cannot remove an open file, so the os.Remove(filename) towards the end of SaveToIndent() fails. This call does not check for errors; if it did, it would show an error similar to:

Unable to remove C:\Users\David.shipped\shipped.ini: remove C:\Users\David.shipped\shipped.ini: The process cannot access the file because it is being used by another process.

read me does not contain a full example

I search on google , this ini package has the most stars.
But it did not have a full example
and no test data ini.
User can hardly use this lib since there is no example

Backlog: v2

  • *file.Section creates new section to *file when section not exists, then *file.NewSection can be removed.

On full COW filesystems os.Create will truncate but never create new file

I found that on a full volume, on a COW filesystem like ZFS, because any write means copy first, if you are saving a change to already existing INI file, truncation with os.Create will happen, but changed contents are not written out, because of the nature of COW.

This is one way of solving this problem. I am not sure it is worth your time, but I do see this as a problem in general. Before a file is saved, we should make sure previous version is not lost until save is known to be good.

My attempt: https://github.com/szaydel/ini/commit/7d5632418e212b9d519f8d31803532dc3a3ee97e

建议struct添加map支持

如果某分区有N个配置项

[test]
a1=a1
a2=a3
..........
aN=aN

配置项是动态的,用 struct 一个一个成员的添加,似乎不太可能.

type Test struct {
    a1 string
    a2 string
    .........
    aN string
}

type Config struct {
    Test  Test 
    Test1 Test1
}

如果支持map就简单多了.

type Config struct {
    Test map[string]string
    Test1 Test1
}

https://github.com/go-ini/ini#other-notes-on-mapreflect
规则可以和这条一样,默认认作一个不同的分区.

Using dots in config keys as separators

Hi, I'm trying to parse a config file that looks like this:

Foo.A = value
Foo.B = value
C = value

into a struct such as

type Configuration struct {
    Foo struct {
        A string
        B string
    }
    C string
} 

However it looks like in order to have a struct like this, my config file needs to be like:

C=...
[Foo]
A=...
B=...

but it is not. So, is there a way to configure the library or my struct to work the way I am trying? Or is it not possible with the existing code?

Parser should respect quoted or escaped delimiter

If we have a field defined as a slice and using space as a delimiter, say:

ExtraArgs   []string `ini:"extra_args" delim:" "`

An entry in the ini file formatted as:

extra_args = aaa bbb ccc

Correctly generates a slice of three string elements, "aaa", "bbb", and "ccc".

However, things get complicated if we need one of the elements to contain a space. I tried the following constructs without success:

extra_args = aaa "bbb and space" ccc

extra_args = aaa bbb\ and\ space ccc

extra_args = """
aaa
bbb and space
ccc"""

And neither seems to work.

Ideally, the delimiter shouldn't be matched inside quoted strings of it it's quoted with a backslash.

Fails if sections have comments on the same line.

For example

[a_section] ;This is my favourite section

It fails because of this code:

    case line[0] == '[' && line[length-1] == ']': // New sction.

It only checks that the first and list characters are [ and ]. If there is a comment then this isn't true.

Allow omitting empty keys

The default golang JSON (un)marshal implementation respects omitempty inside a field's tag which will effectively omit such field from the resulting JSON if it's not defined in a given struct.

Field int `json:"myName,omitempty"`

I was wondering if there's any interest in such feature for this library - i.e. support something like this:

type Profile struct {
    First  string `ini:"first"`
    Second string `ini:"second,omitempty"`
}

The current implementation doesn't interpret commas in any special way which results in the following output:

[my-section]
first            = custom-value
second,omitempty = 

The expected behaviour would be

[my-section]
first = custom-value

Is there any reason to support commas inside key names? 😺

Consider supporting filesystem lock mechanisms

Obviously concurrent changes to the same ini file are now prevented via sync.RWMutex.
This in-memory lock is totally sufficient for most use cases where user needs some safety checks in the same process, but I found myself in situation where I would find an actual file-lock handy.

e.g. to prevent user from opening the file in their editor and start editing the ini file while a go program (using this library) interacts with it.

I think there may be a way to implement this in a way that it doesn't break cross-platform compatibility - just have it gracefully degrade - on systems that don't support flock.

https://golang.org/pkg/syscall/#Flock

Any thoughts - any reasons why a potential PR would not be accepted?

Mapper 没效果 并且有异常

type Info struct{
    PackageName string
}

func t7() {
    i := &Info{}
    err := ini.MapToWithMapper(&i, ini.TitleUnderscore, []byte("packag_name=ini"))
    if err != nil { panic(err) }
    fmt.Printf("%#v\n",i)

    cfg, err := ini.Load("PACKAGE_NAME=ini")
    // ...
    info := new(Info)
    cfg.NameMapper = ini.AllCapsUnderscore
    info.PackageName="A"
    fmt.Printf("%#v\n",info)
    err = cfg.MapTo(info)
    fmt.Printf("%#v\n",info)
    // ...
}

输出为

&main.Info{PackageName:""}
&main.Info{PackageName:"A"}
panic: runtime error: invalid memory address or nil pointer dereference
goroutine 1 [running]:
github.com/go-ini/ini.(*Section).parseFieldName(0x0, 0x44bb970, 0xb, 0x0, 0x0, 0x0, 0x0)
    /Users/wener/go/src/github.com/go-ini/ini/struct.go:63 +0x5a
github.com/go-ini/ini.(*Section).mapTo(0x0, 0x4431fe0, 0xc208098520, 0xd9, 0x0, 0x0)
    /Users/wener/go/src/github.com/go-ini/ini/struct.go:157 +0x2b6
github.com/go-ini/ini.(*Section).MapTo(0x0, 0x438c3e0, 0xc208098520, 0x0, 0x0)
    /Users/wener/go/src/github.com/go-ini/ini/struct.go:199 +0x151
github.com/go-ini/ini.(*File).MapTo(0xc20804afc0, 0x438c3e0, 0xc208098520, 0x0, 0x0)
    /Users/wener/go/src/github.com/go-ini/ini/struct.go:204 +0x70

Dump file contents to a struct

In my use case I need to have a separate struct (initiated and populated) and a *Section instance to be able to get/set data from/to a file.

I believe I could merge outputs of *Section.Keys() (that's values) and *Section.KeyStrings() (that's keys, essentially) I guess, but this should be included in the library.

Reason for this: I need to be able to change data in a file and change data in the instance (obviously, a populated struct is needed) independently. If I would need those in sync, I'd just do a Reload.

how to support sections with same name

i.e.

[entry]
id=1
entry_attr1=a
entry_attr2=b

[entry]
id=2
entry_attr1=c
entry_attr2=d

It seems go-ini doesn't support this situation. it always gets the last one of them. Or there is another way to solve this?

Explicit DEFAULT section when writing to file

Currently, when adding/modifying a key in the DEFAULT section, there is no way to explicitly write the section name. For example, if I had an existing file, config.ini:

[DEFAULT]
key1 = value1

[another_section]
another_key = another_value

If I modified key1 like so:

cfg, _ := ini.Load("config.ini")
key := cfg.Section("DEFAULT").Key("key1")
key.SetValue("value2")
cfg.SaveTo("config.ini")

This would strip the explicit [DEFAULT] section name from the file, resulting in:

key1 = value2

[another_section]
another_key = another_value

It would be great to have the ability to specify including the explicit DEFAULT section header.

Values not saved with Must... methods

When saving with ini.saveTo() the target file is created or replaced succesfully. However, it contains proper section names and keys, but all the values are missing.

I have verified the values contain data by performing fmt.Printf output right before calling ini.saveTo()

Platform: Go 1.6.1, Mac OS 10.11.4

This is how the contents look like:
2016-04-27 18 02 05

Panic when submitting non-existing files to Load()

Hi,

I'm submitting a slice of three files to ini.Load():

cfg, err := ini.Load("/etc/securepass.conf", "/usr/local/etc/securepass.conf", "securepass.conf")

Only the latter exists and has the correct permissions set. Likewise the Python ConfigParser module, it would be great if the function could read the configuration from only those accessible or return an empty configuration if no existing files were provided.

$ ~/go/src/github.com/garlsecurity/go-securepass$ go run spctl/main.go 
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x4811b2]

goroutine 1 [running]:
gopkg.in/ini%2ev1.(*File).GetSection(0x0, 0x7fa130, 0x7, 0x0, 0x0, 0x0)
    /home/SMARTODDS/tregliaa/go/src/gopkg.in/ini.v1/ini.go:976 +0x72
main.loadConfiguration()
    /home/SMARTODDS/tregliaa/go/src/github.com/garlsecurity/go-securepass/spctl/main.go:50 +0xc2
main.main()
    /home/SMARTODDS/tregliaa/go/src/github.com/garlsecurity/go-securepass/spctl/main.go:60 +0x1c

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:1721 +0x1
exit status 2

Thanks for considering.

Writing example

If I'm not mistaken, there is no example in the readme how to write the content back to the file. I found it in the code (cmd.SaveTo(filename))but a simple example would be nice for others.

string with too many zeros?

I dont know if this is expected but when do: (imagine we have a value that prints "2")

 r := key.Value()
fmt.Println(r) //The result is "2"

//If I compare r with "2"
if r == "2" {
//This never happen because misteriously r and "2" are defferent despite both print the same value.
}

so I noticed that when I do len(r) is like 958
but len("2") is 1

so if I do fmt.Println([]byte(r))
it prints something like
[50 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... 0]

edit: actually was a problem in my code while using a buffer. But I can't delete an issue

GetKey auto-creates all child sections

When calling GetKey in a section with dots in the section name, child sections are created.

So I have a ini file with a section with dots in the name:

[[email protected]]
id = bleh

I read the file in, modify the id key and write the file back out and end up with this:

[[email protected]]
id = bleh

[[email protected]]

[john@example]

I think the problem is here, where GetKey calls Section for all child nodes: https://github.com/go-ini/ini/blob/v1/ini.go#L516

It should instead check if each section exists, rather than auto-creating it.

Feature: SaveTo without Indentation

It should be possible to write the values without Indentation in SaveTo. Perhaps with an optional parameter.

[section]
key = value
keylong = value

instead of

[section]
key ________ = value
keylong ____ = value

_ stands for spaces

ReflectFrom with embeded structs panics

Reproduce script:

package main

import (
    "bytes"
    "fmt"

    "gopkg.in/ini.v1"
)

type Struct1 struct {
    Field1 string
}

type Struct2 struct {
    Struct1
}

func main() {
    v := Struct2{Struct1{"foobar"}}

    cfg := ini.Empty()
    if err := cfg.ReflectFrom(&v); err != nil {
        fmt.Printf("Ops: %v", err)
    }

    buff := bytes.NewBuffer(nil)
    cfg.WriteTo(buff)
    fmt.Println(buff.String())
}

The above gives the following output:

panic: interface conversion: interface is main.Struct1, not time.Time

goroutine 1 [running]:
panic(0x5166c0, 0x10a6bbe0)
        C:/GOROOT/src/runtime/panic.go:481 +0x326
gopkg.in/ini%2ev1.reflectWithProperType(0x8d4068, 0x514f20, 0x10a6bbc0, 0x514f20, 0x10a88168, 0x199, 0x52c970, 0x1, 0x0, 0x0)
        D:/Go/src/gopkg.in/ini.v1/struct.go:318 +0x30a
gopkg.in/ini%2ev1.(*Section).reflectFrom(0x10a66390, 0x514f80, 0x10a88168, 0x199, 0x0, 0x0)
        D:/Go/src/gopkg.in/ini.v1/struct.go:393 +0x72a
gopkg.in/ini%2ev1.(*Section).ReflectFrom(0x10a66390, 0x4ebd80, 0x10a88168, 0x0, 0x0)
        D:/Go/src/gopkg.in/ini.v1/struct.go:412 +0x149
gopkg.in/ini%2ev1.(*File).ReflectFrom(0x10a68580, 0x4ebd80, 0x10a88168, 0x0, 0x0)
        D:/Go/src/gopkg.in/ini.v1/struct.go:417 +0x51
main.main()
        C:/Users/andrey.nering/Desktop/ini_reproduce.go:22 +0x93
exit status 2

I guess the error started after 959d90a

I suspect from this and this lines.

Given that reflect.TypeOf(time.Now()).Kind() is struct, so any struct will match that line. See https://play.golang.org/p/16o9O2eDNq

Checkouting to 927d8d7 (one commit before the cited) fixed this issue for me.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.