Skip to content

Commit 1fd9d22

Browse files
committed
go-aah/aah#156 integrate config lib with VFS
1 parent feeaeeb commit 1fd9d22

File tree

2 files changed

+68
-57
lines changed

2 files changed

+68
-57
lines changed

config.go

+55-41
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,18 +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

2121
var errKeyNotFound = errors.New("config: not found")
2222

23-
// NewEmptyConfig method returns aah empty config instance.
24-
func NewEmptyConfig() *Config {
23+
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
24+
// Package methods
25+
//______________________________________________________________________________
26+
27+
// NewEmpty method returns aah empty config instance.
28+
func NewEmpty() *Config {
2529
cfg, _ := ParseString("")
2630
return cfg
2731
}
2832

33+
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
34+
// Config type and methods
35+
//______________________________________________________________________________
36+
2937
// Config handles the configuration values and enables environment profile's,
3038
// merge, etc. Also it provide nice and handly methods for accessing config values.
3139
// Internally `aah config` uses `forge syntax` developed by `https://github.com/brettlangdon`.
@@ -63,6 +71,9 @@ func (c *Config) HasProfile(profile string) bool {
6371

6472
// IsProfileEnabled returns true of profile enabled otherwise false
6573
func (c *Config) IsProfileEnabled() bool {
74+
if c == nil {
75+
return false
76+
}
6677
return len(c.profile) > 0
6778
}
6879

@@ -206,9 +217,9 @@ func (c *Config) Get(key string) (interface{}, bool) {
206217
return c.get(key)
207218
}
208219

209-
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
220+
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
210221
// List methods
211-
//___________________________________
222+
//______________________________________________________________________________
212223

213224
// StringList method returns the string slice value for the given key.
214225
// Eaxmple:-
@@ -303,9 +314,9 @@ func (c *Config) Int64List(key string) ([]int64, bool) {
303314
return values, true
304315
}
305316

306-
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
307-
// Setter methods
308-
//___________________________________
317+
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
318+
// Config Setter methods
319+
//______________________________________________________________________________
309320

310321
// SetString sets the given value string for config key
311322
// First it tries to get value within enabled profile
@@ -380,36 +391,33 @@ func (c *Config) ToJSON() string {
380391
return "{}"
381392
}
382393

383-
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
384-
// Configuration loading methods
385-
//___________________________________
394+
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
395+
// Config load/parse methods
396+
//______________________________________________________________________________
386397

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

398-
return &Config{
399-
cfg: setting,
400-
}, 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
401407
}
402408

403-
// LoadFiles loads the configuration given config files and
404-
// 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.
405411
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) {
406418
settings := forge.NewSection()
407419
for _, file := range files {
408-
if !ess.IsFileExists(file) {
409-
return nil, fmt.Errorf("configuration does not exists: %v", file)
410-
}
411-
412-
setting, err := forge.ParseFile(file)
420+
setting, err := loadFile(fs, file)
413421
if err != nil {
414422
return nil, err
415423
}
@@ -419,9 +427,7 @@ func LoadFiles(files ...string) (*Config, error) {
419427
}
420428
}
421429

422-
return &Config{
423-
cfg: settings,
424-
}, nil
430+
return &Config{cfg: settings}, nil
425431
}
426432

427433
// ParseString parses the configuration values from string
@@ -430,15 +436,19 @@ func ParseString(cfg string) (*Config, error) {
430436
if err != nil {
431437
return nil, err
432438
}
433-
434-
return &Config{
435-
cfg: setting,
436-
}, nil
439+
return &Config{cfg: setting}, nil
437440
}
438441

439-
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
440-
// Unexported methods
441-
//___________________________________
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+
}
442452

443453
func (c *Config) prepareKey(key string) string {
444454
if c.IsProfileEnabled() {
@@ -475,6 +485,10 @@ func (c *Config) getListValue(key string) (*forge.List, bool) {
475485
}
476486

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

config_test.go

+13-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")
@@ -263,7 +263,7 @@ func TestIntAndInt64List(t *testing.T) {
263263
}
264264

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

268268
t.Log(cfg.cfg.Keys())
269269

@@ -276,9 +276,7 @@ func TestProfile(t *testing.T) {
276276
}
277277

278278
func TestConfigLoadNotExists(t *testing.T) {
279-
testdataPath := getTestdataPath()
280-
281-
_, err := LoadFile(join(testdataPath, "not_exists.cfg"))
279+
_, err := LoadFile(join(testdataBaseDir(), "not_exists.cfg"))
282280
assert.True(t, strings.HasPrefix(err.Error(), "configuration does not exists:"))
283281

284282
_, err = ParseString(`
@@ -336,7 +334,7 @@ prod {
336334
}
337335

338336
func TestLoadFiles(t *testing.T) {
339-
testdataPath := getTestdataPath()
337+
testdataPath := testdataBaseDir()
340338

341339
cfg, err := LoadFiles(
342340
join(testdataPath, "test-1.cfg"),
@@ -371,7 +369,7 @@ func TestLoadFiles(t *testing.T) {
371369
}
372370

373371
func TestNestedKeyWithProfile(t *testing.T) {
374-
testdataPath := getTestdataPath()
372+
testdataPath := testdataBaseDir()
375373

376374
cfg, err := LoadFiles(join(testdataPath, "test-4.cfg"))
377375
assert.FailNowOnError(t, err, "loading failed")
@@ -399,7 +397,7 @@ func TestNestedKeyWithProfile(t *testing.T) {
399397
}
400398

401399
func TestConfigSetValues(t *testing.T) {
402-
testdataPath := getTestdataPath()
400+
testdataPath := testdataBaseDir()
403401
cfg, err := LoadFiles(join(testdataPath, "test-4.cfg"))
404402
assert.FailNowOnError(t, err, "loading failed")
405403

@@ -429,7 +427,6 @@ func initString(t *testing.T, configStr string) *Config {
429427
func initFile(t *testing.T, file string) *Config {
430428
cfg, err := LoadFile(file)
431429
assert.FailNowOnError(t, err, "")
432-
433430
return cfg
434431
}
435432

@@ -438,7 +435,7 @@ func setProfileForTest(t *testing.T, cfg *Config, profile string) {
438435
assert.FailNowOnError(t, err, "")
439436
}
440437

441-
func getTestdataPath() string {
438+
func testdataBaseDir() string {
442439
wd, _ := os.Getwd()
443440
return filepath.Join(wd, "testdata")
444441
}

0 commit comments

Comments
 (0)