Skip to content

Commit

Permalink
Config File Handling (#156)
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-kar authored Oct 17, 2024
1 parent d088f1d commit 3b5daaa
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 37 deletions.
100 changes: 64 additions & 36 deletions cmd/iceberg/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (

"github.com/apache/iceberg-go"
"github.com/apache/iceberg-go/catalog"
"github.com/apache/iceberg-go/config"
"github.com/apache/iceberg-go/table"
"github.com/docopt/docopt-go"
)
Expand Down Expand Up @@ -58,54 +59,63 @@ Options:
--uri TEXT specify the catalog URI
--output TYPE output type (json/text) [default: text]
--credential TEXT specify credentials for the catalog
--warehouse TEXT specify the warehouse to use`
--warehouse TEXT specify the warehouse to use
--config TEXT specify the path to the configuration file`

type Config struct {
List bool `docopt:"list"`
Describe bool `docopt:"describe"`
Schema bool `docopt:"schema"`
Spec bool `docopt:"spec"`
Uuid bool `docopt:"uuid"`
Location bool `docopt:"location"`
Props bool `docopt:"properties"`
Drop bool `docopt:"drop"`
Files bool `docopt:"files"`
Rename bool `docopt:"rename"`

Get bool `docopt:"get"`
Set bool `docopt:"set"`
Remove bool `docopt:"remove"`

Namespace bool `docopt:"namespace"`
Table bool `docopt:"table"`

RenameFrom string `docopt:"<from>"`
RenameTo string `docopt:"<to>"`

Parent string `docopt:"PARENT"`
Ident string `docopt:"IDENTIFIER"`
TableID string `docopt:"TABLE_ID"`
PropName string `docopt:"PROPNAME"`
Value string `docopt:"VALUE"`

Catalog string `docopt:"--catalog"`
URI string `docopt:"--uri"`
Output string `docopt:"--output"`
History bool `docopt:"--history"`
Cred string `docopt:"--credential"`
Warehouse string `docopt:"--warehouse"`
Config string `docopt:"--config"`
}

func main() {
args, err := docopt.ParseArgs(usage, os.Args[1:], iceberg.Version())
if err != nil {
log.Fatal(err)
}

cfg := struct {
List bool `docopt:"list"`
Describe bool `docopt:"describe"`
Schema bool `docopt:"schema"`
Spec bool `docopt:"spec"`
Uuid bool `docopt:"uuid"`
Location bool `docopt:"location"`
Props bool `docopt:"properties"`
Drop bool `docopt:"drop"`
Files bool `docopt:"files"`
Rename bool `docopt:"rename"`

Get bool `docopt:"get"`
Set bool `docopt:"set"`
Remove bool `docopt:"remove"`

Namespace bool `docopt:"namespace"`
Table bool `docopt:"table"`

RenameFrom string `docopt:"<from>"`
RenameTo string `docopt:"<to>"`

Parent string `docopt:"PARENT"`
Ident string `docopt:"IDENTIFIER"`
TableID string `docopt:"TABLE_ID"`
PropName string `docopt:"PROPNAME"`
Value string `docopt:"VALUE"`

Catalog string `docopt:"--catalog"`
URI string `docopt:"--uri"`
Output string `docopt:"--output"`
History bool `docopt:"--history"`
Cred string `docopt:"--credential"`
Warehouse string `docopt:"--warehouse"`
}{}
cfg := Config{}

if err := args.Bind(&cfg); err != nil {
log.Fatal(err)
}

fileCfg := config.ParseConfig(config.LoadConfig(cfg.Config), "default")
if fileCfg != nil {
mergeConf(fileCfg, &cfg)
}

var output Output
switch strings.ToLower(cfg.Output) {
case "text":
Expand Down Expand Up @@ -341,3 +351,21 @@ func properties(output Output, cat catalog.Catalog, args propCmd) {
}
}
}

func mergeConf(fileConf *config.CatalogConfig, resConfig *Config) {
if len(resConfig.Catalog) == 0 {
resConfig.Catalog = fileConf.Catalog
}
if len(resConfig.URI) == 0 {
resConfig.URI = fileConf.URI
}
if len(resConfig.Output) == 0 {
resConfig.Output = fileConf.Output
}
if len(resConfig.Cred) == 0 {
resConfig.Cred = fileConf.Credential
}
if len(resConfig.Warehouse) == 0 {
resConfig.Warehouse = fileConf.Warehouse
}
}
71 changes: 71 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package config

import (
"os"
"path/filepath"

"gopkg.in/yaml.v3"
)

const cfgFile = ".iceberg-go.yaml"

type Config struct {
Catalogs map[string]CatalogConfig `yaml:"catalog"`
}

type CatalogConfig struct {
Catalog string `yaml:"catalog"`
URI string `yaml:"uri"`
Output string `yaml:"output"`
Credential string `yaml:"credential"`
Warehouse string `yaml:"warehouse"`
}

func LoadConfig(configPath string) []byte {
var path string
if len(configPath) > 0 {
path = configPath
} else {
homeDir, err := os.UserHomeDir()
if err != nil {
return nil

}
path = filepath.Join(homeDir, cfgFile)
}
file, err := os.ReadFile(path)
if err != nil {
return nil
}
return file
}

func ParseConfig(file []byte, catalogName string) *CatalogConfig {
var config Config
err := yaml.Unmarshal(file, &config)
if err != nil {
return nil
}
res, ok := config.Catalogs[catalogName]
if !ok {
return nil
}
return &res
}
85 changes: 85 additions & 0 deletions config/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package config

import (
"testing"

"github.com/stretchr/testify/assert"
)

var testArgs = []struct {
file []byte
catName string
expected *CatalogConfig
}{
// config file does not exist
{nil, "default", nil},
// config does not have default catalog
{[]byte(`
catalog:
custom-catalog:
catalog: rest
uri: http://localhost:8181/
output: text
credential: client-id:client-secret
warehouse: catalog_name
`), "default", nil},
// default catalog
{[]byte(`
catalog:
default:
catalog: rest
uri: http://localhost:8181/
output: text
credential: client-id:client-secret
warehouse: catalog_name
`), "default",
&CatalogConfig{
Catalog: "rest",
URI: "http://localhost:8181/",
Output: "text",
Credential: "client-id:client-secret",
Warehouse: "catalog_name",
}},
// custom catalog
{[]byte(`
catalog:
custom-catalog:
catalog: rest
uri: http://localhost:8181/
output: text
credential: client-id:client-secret
warehouse: catalog_name
`), "custom-catalog",
&CatalogConfig{
Catalog: "rest",
URI: "http://localhost:8181/",
Output: "text",
Credential: "client-id:client-secret",
Warehouse: "catalog_name",
}},
}

func TestParseConfig(t *testing.T) {
for _, tt := range testArgs {
actual := ParseConfig([]byte(tt.file), tt.catName)

assert.Equal(t, tt.expected, actual)
}
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ require (
github.com/twmb/murmur3 v1.1.8
github.com/wolfeidau/s3iofs v1.5.2
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0
gopkg.in/yaml.v3 v3.0.1
)

require (
Expand Down Expand Up @@ -87,5 +88,4 @@ require (
golang.org/x/text v0.18.0 // indirect
golang.org/x/tools v0.25.0 // indirect
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

0 comments on commit 3b5daaa

Please sign in to comment.