Skip to content

Commit

Permalink
feat: add optional file flags for cli view add command
Browse files Browse the repository at this point in the history
  • Loading branch information
najeal committed Dec 11, 2024
1 parent 648924e commit f25ee17
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 14 deletions.
64 changes: 50 additions & 14 deletions cli/view_add.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ import (
)

func MakeViewAddCommand() *cobra.Command {
var queryFile string
var sdlFile string
var lensFile string
var cmd = &cobra.Command{
cmd := &cobra.Command{
Use: "add [query] [sdl] [transform]",
Short: "Add new view",
Long: `Add new database view.
Expand All @@ -36,25 +38,26 @@ Learn more about the DefraDB GraphQL Schema Language on https://docs.source.netw
RunE: func(cmd *cobra.Command, args []string) error {
store := mustGetContextStore(cmd)

query := args[0]
sdl := args[1]
fileOrArg := newFileOrArgData(args, os.ReadFile)
query, err := fileOrArg.next(queryFile)
if err != nil {
return err
}
sdl, err := fileOrArg.next(sdlFile)
if err != nil {
return err
}
lensCfgJson, err := fileOrArg.next(lensFile)
if err != nil {
return err
}

var lensCfgJson string
switch {
case lensFile != "":
data, err := os.ReadFile(lensFile)
if err != nil {
return err
}
lensCfgJson = string(data)
case len(args) == 3 && args[2] == "-":
if lensCfgJson == "-" {
data, err := io.ReadAll(cmd.InOrStdin())
if err != nil {
return err
}
lensCfgJson = string(data)
case len(args) == 3:
lensCfgJson = args[2]
}

var transform immutable.Option[model.Lens]
Expand All @@ -77,5 +80,38 @@ Learn more about the DefraDB GraphQL Schema Language on https://docs.source.netw
},
}
cmd.Flags().StringVarP(&lensFile, "file", "f", "", "Lens configuration file")
cmd.Flags().StringVarP(&queryFile, "query-file", "", "", "Query file")
cmd.Flags().StringVarP(&sdlFile, "sdl-file", "", "", "SDL file")
return cmd
}

type readFileFn func(string) ([]byte, error)

// FileOrArgData tracks a serie of args.
type FileOrArgData struct {
args []string
currentIndex int
readFile readFileFn
}

func newFileOrArgData(args []string, readFile readFileFn) FileOrArgData {
return FileOrArgData{
args: args,
currentIndex: 0,
readFile: readFile,
}
}

// next gets the data primarily from a file when filePath is set, or from expected arg index.
func (x *FileOrArgData) next(filePath string) (string, error) {
if filePath == "" {
data := x.args[x.currentIndex]
x.currentIndex += 1
return data, nil
}
data, err := x.readFile(filePath)
if err != nil {
return "", err
}
return string(data), nil
}
83 changes: 83 additions & 0 deletions cli/view_add_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright 2023 Democratized Data Foundation
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

package cli

import (
"fmt"
"testing"

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

func TestFileOrArgData(t *testing.T) {
tests := []struct {
name string
args []string
filePaths []string
expectedRes []string
readFile readFileFn
}{
{
name: "NoFile",
args: []string{"arg0", "arg1", "arg2"},
filePaths: []string{"", "", ""},
expectedRes: []string{"arg0", "arg1", "arg2"},
},
{
name: "FileFirst",
args: []string{"arg1", "arg2"},
filePaths: []string{"file0", "", ""},
expectedRes: []string{"file0", "arg1", "arg2"},
},
{
name: "FileMiddle",
args: []string{"arg0", "arg2"},
filePaths: []string{"", "file0", ""},
expectedRes: []string{"arg0", "file0", "arg2"},
},
{
name: "FileLast",
args: []string{"arg0", "arg1"},
filePaths: []string{"", "", "file0"},
expectedRes: []string{"arg0", "arg1", "file0"},
},
{
name: "FileFirstLast",
args: []string{"arg1"},
filePaths: []string{"file0", "", "file1"},
expectedRes: []string{"file0", "arg1", "file1"},
},
}

for _, test := range tests {
fileReader := newMockReadFile()
getData := newFileOrArgData(test.args, fileReader.Read)
for i := range test.filePaths {
res, err := getData.next(test.filePaths[i])
require.NoError(t, err)
require.Equal(t, test.expectedRes[i], res)
}
}
}

type mockReadFile struct {
index int
}

func newMockReadFile() mockReadFile {
return mockReadFile{}
}

func (f *mockReadFile) Read(string) ([]byte, error) {
data := []byte(fmt.Sprintf("file%d", f.index))
f.index += 1
return data, nil
}

0 comments on commit f25ee17

Please sign in to comment.