Skip to content

Commit 4a83ecc

Browse files
authored
Merge pull request #8 for v0.5.0 Release
2 parents 5e0e808 + 96e36cd commit 4a83ecc

File tree

6 files changed

+109
-73
lines changed

6 files changed

+109
-73
lines changed

.travis.yml

+6-4
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,19 @@ branches:
77
# skip tags build, we are building branch and master that is enough for
88
# consistenty check and release. Let's use Travis CI resources optimally
99
# for aah framework.
10-
- /^v[0-9]\.[0-9]/
10+
- /^v[0-9.]+$/
1111

1212
go:
13-
- 1.8
14-
- 1.8.x
13+
- 1.9.x
14+
- 1.x
1515
- tip
1616

1717
go_import_path: aahframework.org/config.v0
1818

19+
before_install:
20+
- bash <(curl -s https://aahframework.org/base-before-install) "essentials vfs forge"
21+
1922
install:
20-
- git config --global http.https://aahframework.org.followRedirects true
2123
- go get -t -v ./...
2224

2325
script:

LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The MIT License (MIT)
22

3-
Copyright (c) 2016-2017 Jeevanandam M., https://myjeeva.com <[email protected]>
3+
Copyright (c) 2016-2018 Jeevanandam M., https://myjeeva.com <[email protected]>
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

+12-10
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
1-
# config - aah framework
1+
<p align="center">
2+
<img src="https://cdn.aahframework.org/assets/img/aah-logo-64x64.png" />
3+
<h2 align="center">Config Library by aah framework</h2>
4+
</p>
5+
<p align="center">
6+
<p align="center"><a href="https://travis-ci.org/go-aah/config"><img src="https://travis-ci.org/go-aah/config.svg?branch=master" alt="Build Status"></a> <a href="https://codecov.io/gh/go-aah/config/branch/master"><img src="https://codecov.io/gh/go-aah/config/branch/master/graph/badge.svg" alt="Code Coverage"></a> <a href="https://goreportcard.com/report/aahframework.org/config.v0"><img src="https://goreportcard.com/badge/aahframework.org/config.v0" alt="Go Report Card"></a> <a href="https://github.com/go-aah/config/releases/latest"><img src="https://img.shields.io/badge/version-0.5.0-blue.svg" alt="Release Version"></a> <a href="https://godoc.org/aahframework.org/config.v0"><img src="https://godoc.org/aahframework.org/config.v0?status.svg" alt="Godoc"></a> <a href="https://twitter.com/aahframework"><img src="https://img.shields.io/badge/[email protected]" alt="Twitter @aahframework"></a></p>
7+
</p>
28

3-
[![Build Status](https://travis-ci.org/go-aah/config.svg?branch=master)](https://travis-ci.org/go-aah/config) [![codecov](https://codecov.io/gh/go-aah/config/branch/master/graph/badge.svg)](https://codecov.io/gh/go-aah/config/branch/master) [![Go Report Card](https://goreportcard.com/badge/aahframework.org/config.v0)](https://goreportcard.com/report/aahframework.org/config.v0)
4-
[![Version](https://img.shields.io/badge/version-0.4.2-blue.svg)](https://github.com/go-aah/config/releases/latest) [![GoDoc](https://godoc.org/aahframework.org/config.v0?status.svg)](https://godoc.org/aahframework.org/config.v0) [![License](https://img.shields.io/github/license/go-aah/config.svg)](LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/aahframework)
9+
`config` library is powerful and flexible to configuration file/structure. It internally uses `forge` library developed by [@brettlangdon](htpps://github.com/brettlangdon) and adds further functionality to it. Syntax is very similar to Typesafe HOCON :satisfied:. Config library is used across the aah framework.
510

6-
***v0.4.2 [released](https://github.com/go-aah/config/releases/latest) and tagged on Jul 30, 2017***
11+
### News
712

8-
`config` library is powerful and flexible for configuration purpose. It's thin layer around `forge` config syntax which is very similar to Typesafe HOCON syntax :satisfied:. aah framework and it's modules is powered with `aah/config` library.
13+
* `v0.5.0` [released](https://github.com/go-aah/config/releases/latest) and tagged on Jun 20, 2018.
914

10-
*`config` developed for aah framework. However it's an independent library, can be used separately with any `Go` language project. Feel free to use it.*
15+
## Installation
1116

12-
# Installation
13-
#### Stable Version - Production Ready
1417
```bash
15-
# install the library
1618
go get -u aahframework.org/config.v0
1719
```
1820

19-
Visit official website https://aahframework.org to learn more.
21+
Visit official website https://aahframework.org to learn more about `aah` framework.

config.go

+59-42
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Copyright (c) Jeevanandam M. (https://github.com/jeevatkm)
2-
// go-aah/config source code and usage is governed by a MIT style
2+
// aahframework.org/config source code and usage is governed by a MIT style
33
// license that can be found in the LICENSE file.
44

55
// Package config is nice and handy layer built around `forge` config syntax;
@@ -14,15 +14,26 @@ import (
1414
"fmt"
1515
"strings"
1616

17-
"aahframework.org/essentials.v0"
1817
"aahframework.org/forge.v0"
18+
"aahframework.org/vfs.v0"
1919
)
2020

21-
// Version no. of aahframework.org/config library
22-
var Version = "0.4.2"
23-
2421
var errKeyNotFound = errors.New("config: not found")
2522

23+
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
24+
// Package methods
25+
//______________________________________________________________________________
26+
27+
// NewEmpty method returns aah empty config instance.
28+
func NewEmpty() *Config {
29+
cfg, _ := ParseString("")
30+
return cfg
31+
}
32+
33+
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
34+
// Config type and methods
35+
//______________________________________________________________________________
36+
2637
// Config handles the configuration values and enables environment profile's,
2738
// merge, etc. Also it provide nice and handly methods for accessing config values.
2839
// Internally `aah config` uses `forge syntax` developed by `https://github.com/brettlangdon`.
@@ -60,6 +71,9 @@ func (c *Config) HasProfile(profile string) bool {
6071

6172
// IsProfileEnabled returns true of profile enabled otherwise false
6273
func (c *Config) IsProfileEnabled() bool {
74+
if c == nil {
75+
return false
76+
}
6377
return len(c.profile) > 0
6478
}
6579

@@ -203,9 +217,9 @@ func (c *Config) Get(key string) (interface{}, bool) {
203217
return c.get(key)
204218
}
205219

206-
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
220+
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
207221
// List methods
208-
//___________________________________
222+
//______________________________________________________________________________
209223

210224
// StringList method returns the string slice value for the given key.
211225
// Eaxmple:-
@@ -300,9 +314,9 @@ func (c *Config) Int64List(key string) ([]int64, bool) {
300314
return values, true
301315
}
302316

303-
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
304-
// Setter methods
305-
//___________________________________
317+
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
318+
// Config Setter methods
319+
//______________________________________________________________________________
306320

307321
// SetString sets the given value string for config key
308322
// First it tries to get value within enabled profile
@@ -377,36 +391,33 @@ func (c *Config) ToJSON() string {
377391
return "{}"
378392
}
379393

380-
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
381-
// Configuration loading methods
382-
//___________________________________
394+
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
395+
// Config load/parse methods
396+
//______________________________________________________________________________
383397

384-
// LoadFile loads the configuration given config file
398+
// LoadFile loads the configuration from given config file.
385399
func LoadFile(file string) (*Config, error) {
386-
if !ess.IsFileExists(file) {
387-
return nil, fmt.Errorf("configuration does not exists: %v", file)
388-
}
389-
390-
setting, err := forge.ParseFile(file)
391-
if err != nil {
392-
return nil, err
393-
}
400+
return VFSLoadFile(nil, file)
401+
}
394402

395-
return &Config{
396-
cfg: setting,
397-
}, nil
403+
// VFSLoadFile loads the configuration from given vfs and config file.
404+
func VFSLoadFile(fs *vfs.VFS, file string) (*Config, error) {
405+
setting, err := loadFile(fs, file)
406+
return &Config{cfg: setting}, err
398407
}
399408

400-
// LoadFiles loads the configuration given config files and
401-
// does merging of configuration in the order they are given
409+
// LoadFiles loads the configuration from given config files.
410+
// It does merging of configuration in the order they are given.
402411
func LoadFiles(files ...string) (*Config, error) {
412+
return VFSLoadFiles(nil, files...)
413+
}
414+
415+
// VFSLoadFiles loads the configuration from given config vfs and files.
416+
// It does merging of configuration in the order they are given.
417+
func VFSLoadFiles(fs *vfs.VFS, files ...string) (*Config, error) {
403418
settings := forge.NewSection()
404419
for _, file := range files {
405-
if !ess.IsFileExists(file) {
406-
return nil, fmt.Errorf("configuration does not exists: %v", file)
407-
}
408-
409-
setting, err := forge.ParseFile(file)
420+
setting, err := loadFile(fs, file)
410421
if err != nil {
411422
return nil, err
412423
}
@@ -416,9 +427,7 @@ func LoadFiles(files ...string) (*Config, error) {
416427
}
417428
}
418429

419-
return &Config{
420-
cfg: settings,
421-
}, nil
430+
return &Config{cfg: settings}, nil
422431
}
423432

424433
// ParseString parses the configuration values from string
@@ -427,15 +436,19 @@ func ParseString(cfg string) (*Config, error) {
427436
if err != nil {
428437
return nil, err
429438
}
430-
431-
return &Config{
432-
cfg: setting,
433-
}, nil
439+
return &Config{cfg: setting}, nil
434440
}
435441

436-
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
437-
// Unexported methods
438-
//___________________________________
442+
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
443+
// Config unexported methods
444+
//______________________________________________________________________________
445+
446+
func loadFile(fs *vfs.VFS, file string) (*forge.Section, error) {
447+
if _, err := vfs.Stat(fs, file); err != nil {
448+
return nil, fmt.Errorf("configuration does not exists: %v", file)
449+
}
450+
return forge.VFSParseFile(fs, file)
451+
}
439452

440453
func (c *Config) prepareKey(key string) string {
441454
if c.IsProfileEnabled() {
@@ -472,6 +485,10 @@ func (c *Config) getListValue(key string) (*forge.List, bool) {
472485
}
473486

474487
func (c *Config) getraw(key string) (forge.Value, bool) {
488+
if c == nil || c.cfg == nil {
489+
return nil, false
490+
}
491+
475492
v, err := c.cfg.Resolve(key)
476493
if err != nil {
477494
return nil, false // not found

config_test.go

+23-16
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import (
1616
)
1717

1818
func TestKeysAndKeysByPath(t *testing.T) {
19-
cfg := initFile(t, join(getTestdataPath(), "test.cfg"))
19+
cfg := initFile(t, join(testdataBaseDir(), "test.cfg"))
2020
keys := cfg.Keys()
2121
assert.True(t, ess.IsSliceContainsString(keys, "prod"))
2222
assert.True(t, ess.IsSliceContainsString(keys, "dev"))
@@ -37,7 +37,7 @@ func TestKeysAndKeysByPath(t *testing.T) {
3737
}
3838

3939
func TestGetSubConfig(t *testing.T) {
40-
cfg := initFile(t, join(getTestdataPath(), "test.cfg"))
40+
cfg := initFile(t, join(testdataBaseDir(), "test.cfg"))
4141

4242
prod, found1 := cfg.GetSubConfig("prod")
4343
assert.NotNil(t, prod)
@@ -64,7 +64,7 @@ func TestGetSubConfig(t *testing.T) {
6464
}
6565

6666
func TestIsExists(t *testing.T) {
67-
cfg := initFile(t, join(getTestdataPath(), "test.cfg"))
67+
cfg := initFile(t, join(testdataBaseDir(), "test.cfg"))
6868
found := cfg.IsExists("prod.string")
6969
assert.True(t, found)
7070

@@ -77,7 +77,7 @@ func TestIsExists(t *testing.T) {
7777
}
7878

7979
func TestStringValues(t *testing.T) {
80-
cfg := initFile(t, join(getTestdataPath(), "test.cfg"))
80+
cfg := initFile(t, join(testdataBaseDir(), "test.cfg"))
8181

8282
v1, _ := cfg.String("string")
8383
assert.Equal(t, "a string", v1)
@@ -100,7 +100,7 @@ func TestStringValues(t *testing.T) {
100100
}
101101

102102
func TestIntValues(t *testing.T) {
103-
bytes, _ := ioutil.ReadFile(join(getTestdataPath(), "test.cfg"))
103+
bytes, _ := ioutil.ReadFile(join(testdataBaseDir(), "test.cfg"))
104104
cfg := initString(t, string(bytes))
105105

106106
v1, _ := cfg.Int("int")
@@ -136,7 +136,7 @@ func TestIntValues(t *testing.T) {
136136
}
137137

138138
func TestFloatValues(t *testing.T) {
139-
cfg := initFile(t, join(getTestdataPath(), "test.cfg"))
139+
cfg := initFile(t, join(testdataBaseDir(), "test.cfg"))
140140

141141
v1, _ := cfg.Float32("float32")
142142
assert.Equal(t, float32(32.2), v1)
@@ -180,7 +180,7 @@ func TestFloatValues(t *testing.T) {
180180
}
181181

182182
func TestBoolValues(t *testing.T) {
183-
bytes, _ := ioutil.ReadFile(join(getTestdataPath(), "test.cfg"))
183+
bytes, _ := ioutil.ReadFile(join(testdataBaseDir(), "test.cfg"))
184184
cfg := initString(t, string(bytes))
185185

186186
v1, _ := cfg.Bool("truevalue")
@@ -215,6 +215,12 @@ func TestStringList(t *testing.T) {
215215
build {
216216
# Valid exclude patterns refer: https://golang.org/pkg/path/filepath/#Match
217217
excludes = ["*_test.go", ".*", "*.bak", "*.tmp", "vendor"]
218+
219+
keys = [
220+
"X3pGTSOuJeEVw989IJ/cEtXUEmy52zs1TZQrU06KUKg=",
221+
"MHJYVThihUrJcxW6wcqyOISTXIsInsdj3xK8QrZbHec=",
222+
"GGekerhihUrJcxW6wcqyOISTXIsInsdj3xK8QrZbHec=",
223+
]
218224
}`)
219225

220226
lst1, found1 := cfg.StringList("build.excludes")
@@ -225,6 +231,10 @@ build {
225231
lst2, found2 := cfg.StringList("name")
226232
assert.False(t, found2)
227233
assert.True(t, len(lst2) == 0)
234+
235+
v, f := cfg.StringList("build.keys")
236+
assert.True(t, f)
237+
assert.True(t, len(v) == 3)
228238
}
229239

230240
func TestIntAndInt64List(t *testing.T) {
@@ -253,7 +263,7 @@ func TestIntAndInt64List(t *testing.T) {
253263
}
254264

255265
func TestProfile(t *testing.T) {
256-
cfg := initFile(t, join(getTestdataPath(), "test.cfg"))
266+
cfg := initFile(t, join(testdataBaseDir(), "test.cfg"))
257267

258268
t.Log(cfg.cfg.Keys())
259269

@@ -266,9 +276,7 @@ func TestProfile(t *testing.T) {
266276
}
267277

268278
func TestConfigLoadNotExists(t *testing.T) {
269-
testdataPath := getTestdataPath()
270-
271-
_, err := LoadFile(join(testdataPath, "not_exists.cfg"))
279+
_, err := LoadFile(join(testdataBaseDir(), "not_exists.cfg"))
272280
assert.True(t, strings.HasPrefix(err.Error(), "configuration does not exists:"))
273281

274282
_, err = ParseString(`
@@ -326,7 +334,7 @@ prod {
326334
}
327335

328336
func TestLoadFiles(t *testing.T) {
329-
testdataPath := getTestdataPath()
337+
testdataPath := testdataBaseDir()
330338

331339
cfg, err := LoadFiles(
332340
join(testdataPath, "test-1.cfg"),
@@ -361,7 +369,7 @@ func TestLoadFiles(t *testing.T) {
361369
}
362370

363371
func TestNestedKeyWithProfile(t *testing.T) {
364-
testdataPath := getTestdataPath()
372+
testdataPath := testdataBaseDir()
365373

366374
cfg, err := LoadFiles(join(testdataPath, "test-4.cfg"))
367375
assert.FailNowOnError(t, err, "loading failed")
@@ -389,7 +397,7 @@ func TestNestedKeyWithProfile(t *testing.T) {
389397
}
390398

391399
func TestConfigSetValues(t *testing.T) {
392-
testdataPath := getTestdataPath()
400+
testdataPath := testdataBaseDir()
393401
cfg, err := LoadFiles(join(testdataPath, "test-4.cfg"))
394402
assert.FailNowOnError(t, err, "loading failed")
395403

@@ -419,7 +427,6 @@ func initString(t *testing.T, configStr string) *Config {
419427
func initFile(t *testing.T, file string) *Config {
420428
cfg, err := LoadFile(file)
421429
assert.FailNowOnError(t, err, "")
422-
423430
return cfg
424431
}
425432

@@ -428,7 +435,7 @@ func setProfileForTest(t *testing.T, cfg *Config, profile string) {
428435
assert.FailNowOnError(t, err, "")
429436
}
430437

431-
func getTestdataPath() string {
438+
func testdataBaseDir() string {
432439
wd, _ := os.Getwd()
433440
return filepath.Join(wd, "testdata")
434441
}

0 commit comments

Comments
 (0)