Skip to content

Commit 647baca

Browse files
vojtabiberleclaude
andcommitted
DMD-919 - Refactor configparser to use Parser struct with logger dependency
Convert standalone functions that use logger to methods on a Parser struct: - Add Parser struct with logger field - Add NewParser constructor - Convert ParseTransformationConfig, ParseCodeBlocks, and helper functions to methods - Keep utility functions that don't use logger as standalone functions - Update fetcher.go to create and use Parser instance - Update tests to use new Parser struct Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 74e8e11 commit 647baca

4 files changed

Lines changed: 38 additions & 28 deletions

File tree

go.sum

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -589,8 +589,6 @@ github.com/keboola/go-oauth2-proxy/v7 v7.13.1-0.20251120082210-251fbcb18c16 h1:m
589589
github.com/keboola/go-oauth2-proxy/v7 v7.13.1-0.20251120082210-251fbcb18c16/go.mod h1:2KeAM0/QPbyUAoky+PXVgQDt/5m0qNcn30z9jh4ig8A=
590590
github.com/keboola/go-utils v1.4.0 h1:WTyj95yrr8O8HxtC8TSTyUcElZiRGDeEdVvDpFo6HUo=
591591
github.com/keboola/go-utils v1.4.0/go.mod h1:IopwJzFz2gh0Yj3fUbIe2eamRoDKzbXvjqFjQyw3ZdQ=
592-
github.com/keboola/keboola-sdk-go/v2 v2.9.0 h1:6yE/A9UMa/DRZzOjZvLlYvQ0/g2nK102vMdlkzph3S8=
593-
github.com/keboola/keboola-sdk-go/v2 v2.9.0/go.mod h1:N/PkJnEHcyHMbVjHPjTdQwj5b9Iajl7PEaFUVtywHKU=
594592
github.com/keboola/keboola-sdk-go/v2 v2.11.0 h1:QBqH9pHdtbpuRuNq8rvMF7Xku/UxDgRqKQlQRY0Umtc=
595593
github.com/keboola/keboola-sdk-go/v2 v2.11.0/go.mod h1:N/PkJnEHcyHMbVjHPjTdQwj5b9Iajl7PEaFUVtywHKU=
596594
github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU=

internal/pkg/llm/twinformat/configparser/parser.go

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,18 @@ import (
1111
"github.com/keboola/keboola-as-code/internal/pkg/log"
1212
)
1313

14+
// Parser parses Keboola configuration data into structured types.
15+
type Parser struct {
16+
logger log.Logger
17+
}
18+
19+
// NewParser creates a new Parser instance.
20+
func NewParser(logger log.Logger) *Parser {
21+
return &Parser{logger: logger}
22+
}
23+
1424
// ParseTransformationConfig parses a Config into TransformationConfig.
15-
func ParseTransformationConfig(ctx context.Context, componentID string, cfg *keboola.ConfigWithRows, logger log.Logger) *TransformationConfig {
25+
func (p *Parser) ParseTransformationConfig(ctx context.Context, componentID string, cfg *keboola.ConfigWithRows) *TransformationConfig {
1626
config := &TransformationConfig{
1727
ID: cfg.ID.String(),
1828
Name: cfg.Name,
@@ -27,50 +37,50 @@ func ParseTransformationConfig(ctx context.Context, componentID string, cfg *keb
2737
return config
2838
}
2939

30-
logger.Debugf(ctx, "Config %s keys: %v", cfg.Name, cfg.Content.Keys())
40+
p.logger.Debugf(ctx, "Config %s keys: %v", cfg.Name, cfg.Content.Keys())
3141

3242
// Parse storage.input.tables and storage.output.tables
33-
parseStorageSection(ctx, config, cfg, logger)
43+
p.parseStorageSection(ctx, config, cfg)
3444

3545
// Parse parameters.blocks for transformation code
36-
parseParametersSection(ctx, config, cfg, logger)
46+
p.parseParametersSection(ctx, config, cfg)
3747

3848
return config
3949
}
4050

4151
// parseStorageSection parses the storage section of a transformation config.
42-
func parseStorageSection(ctx context.Context, config *TransformationConfig, cfg *keboola.ConfigWithRows, logger log.Logger) {
52+
func (p *Parser) parseStorageSection(ctx context.Context, config *TransformationConfig, cfg *keboola.ConfigWithRows) {
4353
storage, ok := cfg.Content.Get("storage")
4454
if !ok {
4555
return
4656
}
4757

4858
storageMap := toStringMap(storage)
4959
if storageMap == nil {
50-
logger.Debugf(ctx, "Config %s storage type: %T", cfg.Name, storage)
60+
p.logger.Debugf(ctx, "Config %s storage type: %T", cfg.Name, storage)
5161
return
5262
}
5363

54-
logger.Debugf(ctx, "Config %s storage keys: %v", cfg.Name, maps.Keys(storageMap))
64+
p.logger.Debugf(ctx, "Config %s storage keys: %v", cfg.Name, maps.Keys(storageMap))
5565
config.InputTables = ParseStorageMappings(storageMap, "input")
5666
config.OutputTables = ParseStorageMappings(storageMap, "output")
5767
}
5868

5969
// parseParametersSection parses the parameters section of a transformation config.
60-
func parseParametersSection(ctx context.Context, config *TransformationConfig, cfg *keboola.ConfigWithRows, logger log.Logger) {
70+
func (p *Parser) parseParametersSection(ctx context.Context, config *TransformationConfig, cfg *keboola.ConfigWithRows) {
6171
params, ok := cfg.Content.Get("parameters")
6272
if !ok {
6373
return
6474
}
6575

6676
paramsMap := toStringMap(params)
6777
if paramsMap == nil {
68-
logger.Debugf(ctx, "Config %s parameters type: %T", cfg.Name, params)
78+
p.logger.Debugf(ctx, "Config %s parameters type: %T", cfg.Name, params)
6979
return
7080
}
7181

72-
logger.Debugf(ctx, "Config %s parameters keys: %v", cfg.Name, maps.Keys(paramsMap))
73-
config.Blocks = ParseCodeBlocks(ctx, paramsMap, logger)
82+
p.logger.Debugf(ctx, "Config %s parameters keys: %v", cfg.Name, maps.Keys(paramsMap))
83+
config.Blocks = p.ParseCodeBlocks(ctx, paramsMap)
7484
}
7585

7686
// toStringMap converts various map types to map[string]any.
@@ -151,11 +161,11 @@ func parseTableMapping(t any) (StorageMapping, bool) {
151161
}
152162

153163
// ParseCodeBlocks parses code blocks from transformation parameters.
154-
func ParseCodeBlocks(ctx context.Context, params map[string]any, logger log.Logger) []*CodeBlock {
164+
func (p *Parser) ParseCodeBlocks(ctx context.Context, params map[string]any) []*CodeBlock {
155165
blocks := make([]*CodeBlock, 0)
156166

157167
// Parse standard blocks format
158-
blocks = append(blocks, parseBlocks(ctx, params, logger)...)
168+
blocks = append(blocks, p.parseBlocks(ctx, params)...)
159169

160170
// Handle Snowflake/SQL transformations that use "queries" instead of "blocks"
161171
if queryBlock := parseQueries(params); queryBlock != nil {
@@ -166,7 +176,7 @@ func ParseCodeBlocks(ctx context.Context, params map[string]any, logger log.Logg
166176
}
167177

168178
// parseBlocks parses the "blocks" section from transformation parameters.
169-
func parseBlocks(ctx context.Context, params map[string]any, logger log.Logger) []*CodeBlock {
179+
func (p *Parser) parseBlocks(ctx context.Context, params map[string]any) []*CodeBlock {
170180
blocks := make([]*CodeBlock, 0)
171181

172182
blocksRaw, ok := params["blocks"]
@@ -180,7 +190,7 @@ func parseBlocks(ctx context.Context, params map[string]any, logger log.Logger)
180190
}
181191

182192
for _, b := range blocksSlice {
183-
if block := parseBlock(ctx, b, logger); block != nil {
193+
if block := p.parseBlock(ctx, b); block != nil {
184194
blocks = append(blocks, block)
185195
}
186196
}
@@ -189,7 +199,7 @@ func parseBlocks(ctx context.Context, params map[string]any, logger log.Logger)
189199
}
190200

191201
// parseBlock parses a single block from the configuration.
192-
func parseBlock(ctx context.Context, b any, logger log.Logger) *CodeBlock {
202+
func (p *Parser) parseBlock(ctx context.Context, b any) *CodeBlock {
193203
blockMap := toStringMap(b)
194204
if blockMap == nil {
195205
return nil
@@ -200,9 +210,9 @@ func parseBlock(ctx context.Context, b any, logger log.Logger) *CodeBlock {
200210
block.Name = name
201211
}
202212

203-
logger.Debugf(ctx, "Block %s keys: %v", block.Name, maps.Keys(blockMap))
213+
p.logger.Debugf(ctx, "Block %s keys: %v", block.Name, maps.Keys(blockMap))
204214

205-
block.Codes = parseCodes(ctx, blockMap, logger)
215+
block.Codes = p.parseCodes(ctx, blockMap)
206216

207217
if block.Name == "" && len(block.Codes) == 0 {
208218
return nil
@@ -212,7 +222,7 @@ func parseBlock(ctx context.Context, b any, logger log.Logger) *CodeBlock {
212222
}
213223

214224
// parseCodes parses the codes within a block.
215-
func parseCodes(ctx context.Context, blockMap map[string]any, logger log.Logger) []*Code {
225+
func (p *Parser) parseCodes(ctx context.Context, blockMap map[string]any) []*Code {
216226
codesRaw, ok := blockMap["codes"]
217227
if !ok {
218228
return nil
@@ -225,7 +235,7 @@ func parseCodes(ctx context.Context, blockMap map[string]any, logger log.Logger)
225235

226236
var codes []*Code
227237
for _, c := range codesSlice {
228-
if code := parseCode(ctx, c, logger); code != nil {
238+
if code := p.parseCode(ctx, c); code != nil {
229239
codes = append(codes, code)
230240
}
231241
}
@@ -234,7 +244,7 @@ func parseCodes(ctx context.Context, blockMap map[string]any, logger log.Logger)
234244
}
235245

236246
// parseCode parses a single code entry from a block.
237-
func parseCode(ctx context.Context, c any, logger log.Logger) *Code {
247+
func (p *Parser) parseCode(ctx context.Context, c any) *Code {
238248
codeMap := toStringMap(c)
239249
if codeMap == nil {
240250
return nil
@@ -245,11 +255,11 @@ func parseCode(ctx context.Context, c any, logger log.Logger) *Code {
245255
code.Name = name
246256
}
247257

248-
logger.Debugf(ctx, "Code %s keys: %v", code.Name, maps.Keys(codeMap))
258+
p.logger.Debugf(ctx, "Code %s keys: %v", code.Name, maps.Keys(codeMap))
249259

250260
code.Script = parseScript(codeMap)
251261

252-
logger.Debugf(ctx, "Code %s script length: %d", code.Name, len(code.Script))
262+
p.logger.Debugf(ctx, "Code %s script length: %d", code.Name, len(code.Script))
253263

254264
if code.Name == "" && code.Script == "" {
255265
return nil

internal/pkg/llm/twinformat/configparser/parser_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ func TestParseCodeBlocks(t *testing.T) {
242242
t.Parallel()
243243

244244
ctx := t.Context()
245-
logger := log.NewNopLogger()
245+
parser := NewParser(log.NewNopLogger())
246246

247247
tests := []struct {
248248
name string
@@ -573,7 +573,7 @@ func TestParseCodeBlocks(t *testing.T) {
573573
for _, tt := range tests {
574574
t.Run(tt.name, func(t *testing.T) {
575575
t.Parallel()
576-
result := ParseCodeBlocks(ctx, tt.params, logger)
576+
result := parser.ParseCodeBlocks(ctx, tt.params)
577577
assert.Equal(t, tt.expected, result)
578578
})
579579
}

internal/pkg/llm/twinformat/fetcher.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ type FetcherDependencies interface {
2424
type Fetcher struct {
2525
api *keboola.AuthorizedAPI
2626
logger log.Logger
27+
parser *configparser.Parser
2728
projectID keboola.ProjectID
2829
telemetry telemetry.Telemetry
2930
}
@@ -33,6 +34,7 @@ func NewFetcher(d FetcherDependencies) *Fetcher {
3334
return &Fetcher{
3435
api: d.KeboolaProjectAPI(),
3536
logger: d.Logger(),
37+
parser: configparser.NewParser(d.Logger()),
3638
projectID: d.ProjectID(),
3739
telemetry: d.Telemetry(),
3840
}
@@ -180,7 +182,7 @@ func (f *Fetcher) FetchTransformationConfigs(ctx context.Context, branchID keboo
180182
}
181183

182184
for _, cfg := range comp.Configs {
183-
config := configparser.ParseTransformationConfig(ctx, comp.ID.String(), cfg, f.logger)
185+
config := f.parser.ParseTransformationConfig(ctx, comp.ID.String(), cfg)
184186
if config == nil {
185187
continue
186188
}

0 commit comments

Comments
 (0)