-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcmdutils.go
More file actions
154 lines (133 loc) · 4.19 KB
/
Copy pathcmdutils.go
File metadata and controls
154 lines (133 loc) · 4.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// pacakge Cmdutils
//
// Wraps around the ConfigManager library
// with additional postprocessing capabilities for
// output management when used with cli flags.
package cmdutils
import (
"fmt"
"io"
"os"
"strings"
"github.com/DevLabFoundry/configmanager/v2/internal/config"
"github.com/DevLabFoundry/configmanager/v2/internal/log"
"github.com/DevLabFoundry/configmanager/v2/pkg/generator"
"github.com/spf13/cobra"
)
type configManagerIface interface {
RetrieveWithInputReplaced(input string) (string, error)
Retrieve(tokens []string) (generator.ParsedMap, error)
GeneratorConfig() *config.GenVarsConfig
}
type CmdUtils struct {
logger log.ILogger
configManager configManagerIface
outputWriter io.WriteCloser
tempOutputWriter io.WriteCloser
}
func New(confManager configManagerIface, logger log.ILogger, writer io.WriteCloser) *CmdUtils {
return &CmdUtils{
logger: logger,
configManager: confManager,
outputWriter: writer,
}
}
// GenerateFromTokens is a helper cmd method to call from retrieve command
func (c *CmdUtils) GenerateFromCmd(tokens []string) error {
return c.generateFromToken(tokens)
}
// generateFromToken
func (c *CmdUtils) generateFromToken(tokens []string) error {
pm, err := c.configManager.Retrieve(tokens)
if err != nil {
// return full error to terminal if no tokens were parsed
// or if strict mode is enabled
if len(pm) < 1 || c.configManager.GeneratorConfig().Strict() {
return err
}
c.logger.Error("%v", err)
}
// Conver to ExportVars and flush to file
pp := &PostProcessor{ProcessedMap: pm, Config: c.configManager.GeneratorConfig()}
pp.ConvertToExportVar()
return pp.FlushOutToFile(c.outputWriter)
}
// Generate a replaced string from string input command
//
// returns a non empty string if move of temp file is required
func (c *CmdUtils) GenerateStrOut(input io.Reader, inputOutputIsSame bool) error {
// outputs and inputs match and are file paths
if inputOutputIsSame {
c.logger.Debug("overwrite mode on")
// create a temp file
tempfile, err := os.CreateTemp(os.TempDir(), "configmanager")
if err != nil {
return err
}
defer os.Remove(tempfile.Name())
c.logger.Debug("tmp file created: %s", tempfile.Name())
c.tempOutputWriter = tempfile
defer c.tempOutputWriter.Close()
return c.generateFromStrOutOverwrite(input, tempfile.Name())
}
return c.generateStrOutFromInput(input, c.outputWriter)
}
// generateFromStrOutOverwrite uses the same file for input as output
// requires additional consideration and must create a temp file
// and then write contents from temp to actual target
// otherwise, two open file operations would be targeting same descriptor
// will cause issues and inconsistent writes
func (c *CmdUtils) generateFromStrOutOverwrite(input io.Reader, outtemp string) error {
if err := c.generateStrOutFromInput(input, c.tempOutputWriter); err != nil {
return err
}
tr, err := os.ReadFile(outtemp)
if err != nil {
return err
}
// move temp file to output path
if _, err := c.outputWriter.Write(tr); err != nil {
return err
}
return nil
}
// generateStrOutFromInput takes a reader and writer as input
func (c *CmdUtils) generateStrOutFromInput(input io.Reader, writer io.Writer) error {
b, err := io.ReadAll(input)
if err != nil {
return err
}
str, err := c.configManager.RetrieveWithInputReplaced(string(b))
if err != nil {
return err
}
pp := &PostProcessor{}
return pp.StrToFile(writer, str)
}
type WriterCloserWrapper struct {
io.Writer
}
func (swc *WriterCloserWrapper) Close() error {
return nil
}
func GetWriter(outputpath string) (io.WriteCloser, error) {
outputWriter := &WriterCloserWrapper{os.Stdout}
if outputpath != "stdout" {
return os.Create(outputpath)
}
return outputWriter, nil
}
func GetReader(cmd *cobra.Command, inputpath string) (io.Reader, error) {
inputReader := cmd.InOrStdin()
if inputpath != "-" && inputpath != "" {
if _, err := os.Stat(inputpath); os.IsNotExist(err) {
return strings.NewReader(inputpath), nil
}
return os.Open(inputpath)
}
return inputReader, nil
}
// UploadTokensWithVals takes in a map of key/value pairs and uploads them
func (c *CmdUtils) UploadTokensWithVals(tokens map[string]string) error {
return fmt.Errorf("notYetImplemented")
}