GithubHelp home page GithubHelp logo

unknwon / goconfig Goto Github PK

View Code? Open in Web Editor NEW
603.0 603.0 145.0 150 KB

Package goconfig is a fully functional and comments-support configuration file (.ini) parser.

License: Apache License 2.0

Go 100.00%
configuration go ini parser

goconfig's Introduction

Hi there 👋

Thanks for visiting my GitHub profile, it's great to meet you here! 😊

Here are some quick things about me:

  • 🔭 I'm a pragmatic software engineer who is paranoid about convention, consistency, and constraints.
  • 🕵️‍♀️ I like doing quality work, and a real asshole on pull request reviews.
  • 🧸 I'm proud of who I am, what I have built, and what I am building.
  • 🧑‍💻 Coding is my passion.
  • 📫 The best way to reach me is to send me an email.
  • ⚡ Fun fact: I once drove to the Half Moon Bay for sun rise (hint: it's on the west coast).
  • 📰 If you like my work, please consider give my newsletter Identity, Authenticity, and Security a look!

goconfig's People

Contributors

admpub avatar codelingoteam avatar jackzerocheng avatar klauspost avatar kqzh avatar likuankuan avatar ncw avatar orthographic-pedant avatar slene avatar unknwon avatar yangjuncode 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

goconfig's Issues

能否提供子Section支持并向上递推返回 key 值

类似文法

keya = default
[section]
keya = aaa
[section.suba]
keyb = bbb

并且根据这种父子关系提供一种向上递推的访问缺省配置的方法
如上面的例子访问
Foo("section.suba","keya")
因为section.suba中没有定义 keya ,section 定义了 keya ,所以返回的是 aaa
如果 section 也没有定义,那继续向上到缺省配置
在内部实现中不必弄成树的形式,也不必明确父子关系,那会让问题复杂
能支持向上递推就好

关于只有key的问题

你好,如果只有key没有value的情况下解析会报错,比如:
nocache
port=
上面这两种情况,会报错,能不能兼容支持第一种,比如my.cnf文件中就有大量的第一种情况。

GetKeyList is missing first key after creating a new section

GetKeyList is missing first key after creating a new section

Here is a demonstration of the problem (playground)

package main

import (
	"bytes"
	"fmt"
	"log"

	"github.com/Unknwon/goconfig"
)

func main() {
	// Make an empty config file
	configData, err := goconfig.LoadFromData([]byte{})
	if err != nil {
		log.Fatalf("Failed to load config file: %v", err)
	}

	// Add two keys to "test" section
	configData.SetValue("test", "key1", "value1")
	configData.SetValue("test", "key2", "value2")

	// Print the keys - only get one "key2"
	fmt.Printf("keys = %v\n", configData.GetKeyList("test"))

	// "save" the config file into a buffer
	var buf bytes.Buffer
	err = goconfig.SaveConfigData(configData, &buf)
	if err != nil {
		log.Fatalf("Failed to save config file: %v", err)
	}

	// show the config file has both keys in
	fmt.Printf("----\n%s----\n", buf.String())
}

This outputs

keys = [key2]  <----- key1 is MISSING here
----
[test]
key1 = value1
key2 = value2

----

But what it should output is this (note extra key1)

keys = [key1 key2]
----
[test]
key1 = value1
key2 = value2

----

保留引号内关键字两端的空格会引发歧义

阅读了您的源码,发现关键字如果在引号内,那么其两端的空格是会被保留的,这会导致一个问题。
比如我初次加载并保存下面的文件:

key_supper = hello
""" key_supper""" = world # 注意:这里key本身包含一个空格

程序处理逻辑认为这是两个不同的关键字,保存后会得到:

key_supper = hello
  key_supper = world # 注意:这里key本身包含一个空格

然后,再次加载处理后的这个文件并保存,程序将关键字两端去空格、覆盖后,会得到

key_supper = world # 注意:这里key本身包含一个空格

最初认为是两个不同的关键字的文件,经过两次加载并保存之后被覆盖成了一个,逻辑上是不一致的。

Bug?空 Section 向上递推无法获取

; ini 数据
[parent]
name=john
relation=father
sex=male
age=32

[parent.child]
age=3

[parent.child.child]

GetValue("parent.child.child", "name")
当 parent.child.child 段没有key,value定义,返回空值,这不正确,
应该是无论 parent.child.child 是否存在或者为空,都能正确向上递推

MAC 上使用报错

goroutine 7 [running]:
github.com/Unknwon/goconfig.(*ConfigFile).GetValue(0x0, 0x176f3f8, 0x3, 0x1774a65, 0x8, 0x0, 0x0, 0x0, 0x0)
/Users/linhai/Downloads/MyProject/Golang_work/src/github.com/Unknwon/goconfig/conf.go:164 +0x67
github.com/Unknwon/goconfig.(*ConfigFile).MustValue(0x0, 0x176f3f8, 0x3, 0x1774a65, 0x8, 0xc42003adf0, 0x1, 0x1, 0xc4201e0000, 0x6d)
/Users/linhai/Downloads/MyProject/Golang_work/src/github.com/Unknwon/goconfig/conf.go:259 +0x57
goodegg-api/commons/log.SetLog()
/Users/linhai/Downloads/MyProject/Golang_work/src/goodegg-api/commons/log/log.go:14 +0xbe
main.(*program).run(0x1aa7b50)
/Users/linhai/Downloads/MyProject/Golang_work/src/goodegg-api/service.go:58 +0x3c
created by main.(*program).Start
/Users/linhai/Downloads/MyProject/Golang_work/src/goodegg-api/service.go:52 +0x3f
exit status 2

DeleteSection would be really useful

DeleteSection would be really useful - it isn't possible at the moment. Deleting all the keys still leaves the section behind.

Thanks for a very useful package

删除section的逻辑问题

test.ini原始内容

[SN]
1 = 1
2 = 2
3 = 3

测试程序:

cfg, err := goconfig.LoadConfigFile("test.ini")
if err != nil {
    fmt.Println(err)
}

fmt.Println(cfg.DeleteSection("SN"))

for i := 1; i < 4; i++ {
    cfg.SetValue("SN", fmt.Sprint(i), fmt.Sprint(i+3))
}

goconfig.SaveConfigFile(cfg, "test.ini")

运行程序后,test.ini内容

[SN]
1 = 4
2 = 5
3 = 6
1 = 4
2 = 5
3 = 6

LoadConfigFile 在 read 错误时不会执行 f.Close()

func LoadConfigFile(fileName string, moreFiles ...string) (c *ConfigFile, err error) {
// Append files' name together.
fileNames := make([]string, 1, len(moreFiles)+1)
fileNames[0] = fileName
if len(moreFiles) > 0 {
fileNames = append(fileNames, moreFiles...)
}

    c = newConfigFile(fileNames)

    for _, name := range fileNames {
            f, err := os.Open(name)
            if err != nil {
                    return nil, err
            }

            if err = c.read(f); err != nil {
                    return nil, err
            }

            if err = f.Close(); err != nil {
                    return nil, err
            }
    }

    return c, nil

}

如上 在

if err = c.read(f); err != nil {
return nil, err
}
发生错误时就不会执行以下语句了吧

if err = f.Close(); err != nil {
return nil, err
}

GetSection返回值并发读写问题

你好,我在使用GetSection的时候,方法内部加了锁,不会出现并发读写问题,
但是返回值是map引用,在外部多线程访问的时候会发生并发读写的问题,这个能在返回的时候返回一个副本吗

conf, _:= cfg.GetSection("QUEUE." + engine)
value, ok := conf["key"]
上面cfg是全局变量,在 第二行就会出现读写问题

是不是可以增加解析相同的key为map

例如
admin=[email protected]
admin=[email protected]

解析为{[email protected],[email protected]}

虽然可以用分隔符,但这样增加修改配置还是更直接方便

类似 https://github.com/itkinside/itkconfig

Lists of key-values

Often a simple Key => Value mapping is not sufficient, and you want a key mapping to an array of values. This if fully supported and you can define your struct as:

type Config struct {
  Foo []string
  Bar []float64
  Zoo []int
}
And then in your config-file:

Foo = string number one.
Foo = string number two.
Bar = 1.0
Bar = 2.0
Zoo = 1
Zoo = 2
Which, you guessed it, will map to the arrays Foo{"string number one.", "string number two"}, Bar{1.0,2.0} and Zoo{1,2}.

GetSectionList doesn't return a copy

GetSectionList returns the actual internal structures, so if you do this you'll get a surprise

for _, key := range ConfigFile.GetKeyList(name) {
    ConfigFile.DeleteKey(name, key)
}

The docs should state that it is a pointer to an internal structure so don't mess with it or iterate over it if you are deleting things.

空行 被解析

[setctor]
如果有空白行,

会被解析为 map[ : ]

例如:

[plugins]

go.mod = 60 true
main.go = 300 true

生成的map :

plugins:map[ : go.mod:60 true main.go:300 true]

生成一个mpa 里有个空 项目

如果 是这个 空 的map 项 是针对 comment 的话.

是否可以考虑增加一个 map["comment"] 项目 , 或者直接去掉 map[ : ] 这个空项

如何创建section

没找到新建section的方法

尝试用cfg.SetValue(section_name, "", "") ,报错

DeleteKey("","key")出错。

ini文件根位置的key删除不了。

如果放在section下是可以的。
cfg.DeleteKey("section","key")
cfg.DeleteSection("section")

保存时ini的部分内容被添加反单引号

info.ini内容:

[info]
temp_max=8
temp_min=2
[time]
total=3
0=0/0/0;2014-04-28 03:31;2014-04-28 18:07;0
1=0/0/0;2014-04-28 18:33;2014-04-28 21:08;0
2=0/0/0;2014-04-28 23:10;2014-04-29 01:35;0
from=2014-04-28 03:31
to=2014-05-07 00:31

cfg.SetValue("info", "temp_min", "0"),保存后内容变成:

[info]
temp_max = 8
temp_min = 0

[time]
total = 3
0 = `0/0/0;2014-04-28 03:31;2014-04-28 18:07;0`
1 = `0/0/0;2014-04-28 18:33;2014-04-28 21:08;0`
2 = `0/0/0;2014-04-28 23:10;2014-04-29 01:35;0`
from = `2014-04-28 03:31`
to = `2014-05-07 00:31`

发现部分内容被添加上反单引号,请问这是怎么回事,还有要如何避免?

can you release a version?

Hello~ community maintainer:
the community has not released a version for a long time, can you release a version?

修改配置文件后写回源文件能否支持原格式?

你好,
在配置文件操作中读配置文件和修改配置文件操作居多,单纯的增加配置项较少,而在使用goconfig修改配置文件并写回到源文件后格式被打乱,例如key与key之间的空行被删除,如果有注释可读性会变差。

请问能否支持在修改配置后不打乱源文件格式写回?
谢谢。

无法保存配置文件到同一个配置文件

    cfg, err := goconfig.LoadConfigFile("client.ini")
    if err != nil {
        log.Println(err)
        return
    }

    var (
        port = cfg.MustValue("client", "port", "7071")
    )

    err := goconfig.SaveConfigFile(cfg,"client.ini")
    if err !=nil {
        log.Println(err)
    }

如果配置文件是空的,或者配置项不全

这样无法写入配置

是特性么?

本来想弄个如果缺少配置项会自动补全什么的……

deepCopy后忘记删除“ ”

	// Remove pre-defined key.
	secMap := deepCopy(c.data[section])
	delete(c.data[section], " ")

应该是

	// Remove pre-defined key.
	secMap := deepCopy(c.data[section])
	delete(secMap, " ")

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.