Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v0.3.0 #10

Merged
merged 1 commit into from
May 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[![Go Version](https://img.shields.io/github/go-mod/go-version/core49/gonfig)](https://go.dev/doc/devel/release#go1.20)
[![Project status](https://img.shields.io/badge/version-0.2.0-green.svg)](https://github.com/core49/gonfig/releases)
[![Project status](https://img.shields.io/badge/version-0.3.0-green.svg)](https://github.com/core49/gonfig/releases)
[![Last commit](https://img.shields.io/github/last-commit/core49/gonfig/main)](https://github.com/core49/gonfig/commits/main)
[![Go Report Card](https://goreportcard.com/badge/github.com/core49/gonfig)](https://goreportcard.com/report/github.com/core49/gonfig)
[![codecov](https://img.shields.io/codecov/c/github/core49/gonfig?token=AO6U2S2I91)](https://codecov.io/gh/core49/gonfig)
Expand Down Expand Up @@ -48,12 +48,12 @@ func main() {
var config YourConfigStruct

// Check if the file exists or if the file is empty
if exists, err := conf.IsEmpty(config); err != nil || exists {
if exists, err := conf.IsEmpty(&config); err != nil || exists {
// handle error or what you want to do if the file exists
}

// Write an empty JSON skeleton of the struct/model to the file
if err := conf.WriteSkeleton(config); err != nil {
if err := conf.WriteSkeleton(&config); err != nil {
// Handle error
}

Expand Down
34 changes: 17 additions & 17 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import (
"time"
)

// New creates a new repository with the given options.
// It applies the flag configuration, generates a default file path if not disabled, and returns the repository
func New(options ...OptionFunc) (Repository, error) {
r := &repository{osArgs: os.Args, fileSystem: afero.NewOsFs()}
// New creates a new Repository with the given options.
// It applies the flag configuration, generates a default file path if not disabled, and returns the Repository
func New(options ...OptionFunc) (Gonfig, error) {
r := &Repository{osArgs: os.Args, fileSystem: afero.NewOsFs()}

for _, optionFunc := range options {
optionFunc(r)
Expand All @@ -34,49 +34,49 @@ func New(options ...OptionFunc) (Repository, error) {

// OptionSetOsArgs sets the os arguments.
func OptionSetOsArgs(osArgs []string) OptionFunc {
return func(r *repository) {
return func(r *Repository) {
r.osArgs = osArgs
}
}

// OptionSetFileSystem sets the file system.
func OptionSetFileSystem(fs afero.Fs) OptionFunc {
return func(r *repository) {
return func(r *Repository) {
r.fileSystem = fs
}
}

// OptionAppendFlagConfig appends the given `flagConfig` to the flag configuration.
func OptionAppendFlagConfig(fc flagConfig) OptionFunc {
return func(r *repository) {
return func(r *Repository) {
r.flagConfiguration = append(r.flagConfiguration, fc)
}
}

// OptionSetFlagConfiguration sets the flag configuration to the given `flagConfiguration`.
func OptionSetFlagConfiguration(fc flagConfiguration) OptionFunc {
return func(r *repository) {
return func(r *Repository) {
r.flagConfiguration = fc
}
}

// OptionDisableDefaultFlagConfiguration disables the default flag configuration.
func OptionDisableDefaultFlagConfiguration(v bool) OptionFunc {
return func(r *repository) {
return func(r *Repository) {
r.disableDefaultFlagConfiguration = v
}
}

// OptionSetConfigFilePathVariable sets the file path and disables default path generation.
func OptionSetConfigFilePathVariable(path string) OptionFunc {
return func(r *repository) {
return func(r *Repository) {
r.filePath = path
r.disableDefaultFilePathGeneration = true
}
}

// applyFlagConfiguration applies flag configurations to command line arguments.
func (r *repository) applyFlagConfiguration() error {
func (r *Repository) applyFlagConfiguration() error {
fmt.Println(r.osArgs)
if len(r.osArgs) == 0 {
return errors.New("os args should not be empty")
Expand Down Expand Up @@ -105,16 +105,16 @@ func (r *repository) applyFlagConfiguration() error {
}

// checkModel verifies that the provided model is a non-nil pointer to a struct type.
func (r *repository) checkModel(model interface{}) error {
func (r *Repository) checkModel(model interface{}) error {
if model == nil || reflect.ValueOf(model).Kind() != reflect.Ptr || reflect.TypeOf(model).Elem().Kind() != reflect.Struct {
return ErrInvalidConfigModel
}

return nil
}

// openFile opens the repository's designated file using the file system.
func (r *repository) openFile() (afero.File, closeFileFunc, error) {
// openFile opens the Repository's designated file using the file system.
func (r *Repository) openFile() (afero.File, closeFileFunc, error) {
if len(r.filePath) == 0 {
return nil, nil, ErrEmptyConfigFilePath
}
Expand All @@ -128,7 +128,7 @@ func (r *repository) openFile() (afero.File, closeFileFunc, error) {
}

// Load loads configuration data from the file at the file path into the given model.
func (r *repository) Load(model interface{}) error {
func (r *Repository) Load(model interface{}) error {
if err := r.checkModel(model); err != nil {
return err
}
Expand All @@ -145,7 +145,7 @@ func (r *repository) Load(model interface{}) error {
}

// WriteSkeleton writes a JSON skeleton of the model to the file path.
func (r *repository) WriteSkeleton(model interface{}) error {
func (r *Repository) WriteSkeleton(model interface{}) error {
if err := r.checkModel(model); err != nil {
return err
}
Expand Down Expand Up @@ -179,7 +179,7 @@ func (r *repository) WriteSkeleton(model interface{}) error {
}

// IsEmpty checks if the config file is empty. Returns `true` if the file does not exist or is empty.
func (r *repository) IsEmpty(model interface{}) (bool, error) {
func (r *Repository) IsEmpty(model interface{}) (bool, error) {
if err := r.checkModel(model); err != nil {
return false, err
}
Expand Down
56 changes: 27 additions & 29 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import (
"time"
)

//go:generate mockgen --build_flags=--mod=mod -destination mock_afero_fs_test.go -package gonfig github.com/spf13/afero Fs

type configModel struct {
Name string `json:"name"`
Version int `json:"version"`
Expand Down Expand Up @@ -113,7 +111,7 @@ func TestNew(t *testing.T) {

func TestOptionSetFileSystem(t *testing.T) {
t.Run("Ok", func(t *testing.T) {
r := &repository{}
r := &Repository{}
require.Empty(t, r.fileSystem)

afs := afero.NewMemMapFs()
Expand All @@ -127,7 +125,7 @@ func TestOptionSetFileSystem(t *testing.T) {

func TestOptionAppendFlagConfig(t *testing.T) {
t.Run("Ok", func(t *testing.T) {
r := &repository{}
r := &Repository{}
fc := flagConfig{
Type: "string",
Name: "test",
Expand All @@ -145,7 +143,7 @@ func TestOptionAppendFlagConfig(t *testing.T) {

func TestOptionSetFlagConfiguration(t *testing.T) {
t.Run("Ok", func(t *testing.T) {
r := &repository{}
r := &Repository{}

optionFunc := OptionSetFlagConfiguration(defaultFlagConfig)
optionFunc(r)
Expand All @@ -156,7 +154,7 @@ func TestOptionSetFlagConfiguration(t *testing.T) {

func TestOptionDisableDefaultFlagConfiguration(t *testing.T) {
t.Run("Ok", func(t *testing.T) {
r := &repository{}
r := &Repository{}

optionFunc := OptionDisableDefaultFlagConfiguration(true)
optionFunc(r)
Expand All @@ -167,7 +165,7 @@ func TestOptionDisableDefaultFlagConfiguration(t *testing.T) {

func TestOptionSetConfigFilePathVariable(t *testing.T) {
t.Run("Ok", func(t *testing.T) {
r := &repository{}
r := &Repository{}

optionFunc := OptionSetConfigFilePathVariable("/tmp/test.json")
optionFunc(r)
Expand All @@ -194,7 +192,7 @@ func TestRepository_Load(t *testing.T) {
_, err = file.Write(j)
require.NoError(t, err)

r := &repository{
r := &Repository{
filePath: "test.json",
fileSystem: afs,
}
Expand All @@ -208,34 +206,34 @@ func TestRepository_Load(t *testing.T) {
t.Run("Fail", func(t *testing.T) {
t.Run("InvalidConfigModel", func(t *testing.T) {
t.Run("Nil", func(t *testing.T) {
r := &repository{}
r := &Repository{}
err := r.Load(nil)

assert.EqualError(t, err, ErrInvalidConfigModel.Error())
})
t.Run("NoneStruct", func(t *testing.T) {
r := &repository{}
r := &Repository{}
err := r.Load("string")

assert.EqualError(t, err, ErrInvalidConfigModel.Error())
})
t.Run("NonePointerStruct", func(t *testing.T) {
r := &repository{}
r := &Repository{}
err := r.Load(configModel{})

assert.EqualError(t, err, ErrInvalidConfigModel.Error())
})
})
t.Run("EmptyFilePath", func(t *testing.T) {
r := &repository{}
r := &Repository{}
err := r.Load(&configModel{})

assert.EqualError(t, err, ErrEmptyConfigFilePath.Error())
})
t.Run("InvalidFilePath", func(t *testing.T) {
afs := afero.NewMemMapFs()

r := &repository{
r := &Repository{
filePath: "not.existing",
fileSystem: afs,
}
Expand All @@ -250,7 +248,7 @@ func TestRepository_WriteSkeleton(t *testing.T) {
t.Run("Ok", func(t *testing.T) {
afs := afero.NewMemMapFs()

r := &repository{
r := &Repository{
filePath: "test.json",
fileSystem: afs,
}
Expand All @@ -276,7 +274,7 @@ func TestRepository_WriteSkeleton(t *testing.T) {
require.NoError(t, err)
require.NoError(t, file.Close())

r := &repository{
r := &Repository{
filePath: "test.json",
fileSystem: afs,
}
Expand All @@ -286,26 +284,26 @@ func TestRepository_WriteSkeleton(t *testing.T) {
})
t.Run("InvalidConfigModel", func(t *testing.T) {
t.Run("Nil", func(t *testing.T) {
r := &repository{}
r := &Repository{}
err := r.WriteSkeleton(nil)

assert.EqualError(t, err, ErrInvalidConfigModel.Error())
})
t.Run("NoneStruct", func(t *testing.T) {
r := &repository{}
r := &Repository{}
err := r.WriteSkeleton("string")

assert.EqualError(t, err, ErrInvalidConfigModel.Error())
})
t.Run("NonePointerStruct", func(t *testing.T) {
r := &repository{}
r := &Repository{}
err := r.WriteSkeleton(configModel{})

assert.EqualError(t, err, ErrInvalidConfigModel.Error())
})
})
t.Run("MarshalIndent", func(t *testing.T) {
r := &repository{}
r := &Repository{}

m := struct {
X chan int
Expand All @@ -315,15 +313,15 @@ func TestRepository_WriteSkeleton(t *testing.T) {
assert.Error(t, err)
})
t.Run("EmptyFilePath", func(t *testing.T) {
r := &repository{}
r := &Repository{}
err := r.WriteSkeleton(&configModel{})

assert.EqualError(t, err, ErrEmptyConfigFilePath.Error())
})
t.Run("InvalidFilePath", func(t *testing.T) {
afs := afero.NewReadOnlyFs(afero.NewMemMapFs())

r := &repository{
r := &Repository{
filePath: "test.json",
fileSystem: afs,
}
Expand All @@ -340,7 +338,7 @@ func TestRepository_IsEmptyConfig(t *testing.T) {
t.Run("FileDoesNotExist", func(t *testing.T) {
afs := afero.NewMemMapFs()

r := &repository{
r := &Repository{
filePath: "test.json",
fileSystem: afs,
}
Expand All @@ -354,7 +352,7 @@ func TestRepository_IsEmptyConfig(t *testing.T) {
t.Run("Empty", func(t *testing.T) {
afs := afero.NewMemMapFs()

r := &repository{
r := &Repository{
filePath: "test.json",
fileSystem: afs,
}
Expand All @@ -374,7 +372,7 @@ func TestRepository_IsEmptyConfig(t *testing.T) {
t.Run("ContainsEmptyJSON", func(t *testing.T) {
afs := afero.NewMemMapFs()

r := &repository{
r := &Repository{
filePath: "test.json",
fileSystem: afs,
}
Expand All @@ -397,7 +395,7 @@ func TestRepository_IsEmptyConfig(t *testing.T) {
t.Run("ContainsValidContent", func(t *testing.T) {
afs := afero.NewMemMapFs()

r := &repository{
r := &Repository{
filePath: "test.json",
fileSystem: afs,
}
Expand Down Expand Up @@ -425,29 +423,29 @@ func TestRepository_IsEmptyConfig(t *testing.T) {
t.Run("Fail", func(t *testing.T) {
t.Run("InvalidConfigModel", func(t *testing.T) {
t.Run("Nil", func(t *testing.T) {
r := &repository{}
r := &Repository{}
exists, err := r.IsEmpty(nil)

assert.EqualError(t, err, ErrInvalidConfigModel.Error())
assert.False(t, exists)
})
t.Run("NoneStruct", func(t *testing.T) {
r := &repository{}
r := &Repository{}
exists, err := r.IsEmpty("string")

assert.EqualError(t, err, ErrInvalidConfigModel.Error())
assert.False(t, exists)
})
t.Run("NonePointerStruct", func(t *testing.T) {
r := &repository{}
r := &Repository{}
exists, err := r.IsEmpty(configModel{})

assert.EqualError(t, err, ErrInvalidConfigModel.Error())
assert.False(t, exists)
})
})
t.Run("EmptyFilePath", func(t *testing.T) {
r := &repository{}
r := &Repository{}
exists, err := r.IsEmpty(&configModel{})

assert.EqualError(t, err, ErrEmptyConfigFilePath.Error())
Expand Down
Loading