From 34bc33d5c5b5ea4da4ba31715f2dfaa3f62fd7dd Mon Sep 17 00:00:00 2001 From: Mike Farah Date: Sat, 9 Jan 2021 11:33:39 +1100 Subject: [PATCH] strenv --- pkg/yqlib/doc/Env Variable Operators.md | 21 +++++++++++++++++++++ pkg/yqlib/lib.go | 1 + pkg/yqlib/operator_env_test.go | 2 +- pkg/yqlib/operators_test.go | 20 +++++++++++++++++--- pkg/yqlib/path_tokeniser.go | 20 ++++++++++++++++++++ 5 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 pkg/yqlib/doc/Env Variable Operators.md diff --git a/pkg/yqlib/doc/Env Variable Operators.md b/pkg/yqlib/doc/Env Variable Operators.md new file mode 100644 index 00000000..6f69515a --- /dev/null +++ b/pkg/yqlib/doc/Env Variable Operators.md @@ -0,0 +1,21 @@ + +## Read boolean environment variable as a string +Running +```bash +myenv="true" yq eval --null-input 'strenv(myenv)' +``` +will output +```yaml +12 +``` + +## Read numeric environment variable as a string +Running +```bash +myenv="12" yq eval --null-input 'strenv(myenv)' +``` +will output +```yaml +12 +``` + diff --git a/pkg/yqlib/lib.go b/pkg/yqlib/lib.go index fbe69dd0..db8402f3 100644 --- a/pkg/yqlib/lib.go +++ b/pkg/yqlib/lib.go @@ -70,6 +70,7 @@ var TraverseArray = &OperationType{Type: "TRAVERSE_ARRAY", NumArgs: 1, Precedenc var DocumentFilter = &OperationType{Type: "DOCUMENT_FILTER", NumArgs: 0, Precedence: 50, Handler: TraversePathOperator} var SelfReference = &OperationType{Type: "SELF", NumArgs: 0, Precedence: 50, Handler: SelfOperator} var ValueOp = &OperationType{Type: "VALUE", NumArgs: 0, Precedence: 50, Handler: ValueOperator} +var EnvOp = &OperationType{Type: "ENV", NumArgs: 0, Precedence: 50, Handler: EnvOperator} var Not = &OperationType{Type: "NOT", NumArgs: 0, Precedence: 50, Handler: NotOperator} var Empty = &OperationType{Type: "EMPTY", NumArgs: 50, Handler: EmptyOperator} diff --git a/pkg/yqlib/operator_env_test.go b/pkg/yqlib/operator_env_test.go index d70cef32..0569e38e 100644 --- a/pkg/yqlib/operator_env_test.go +++ b/pkg/yqlib/operator_env_test.go @@ -27,5 +27,5 @@ func TestEnvOperatorScenarios(t *testing.T) { for _, tt := range envOperatorScenarios { testScenario(t, &tt) } - documentScenarios(t, "Env Variable Operators", addOperatorScenarios) + documentScenarios(t, "Env Variable Operators", envOperatorScenarios) } diff --git a/pkg/yqlib/operators_test.go b/pkg/yqlib/operators_test.go index c8881bb5..5064410f 100644 --- a/pkg/yqlib/operators_test.go +++ b/pkg/yqlib/operators_test.go @@ -17,6 +17,7 @@ import ( type expressionScenario struct { description string subdescription string + environmentVariable string document string document2 string expression string @@ -61,6 +62,10 @@ func testScenario(t *testing.T, s *expressionScenario) { } + if s.environmentVariable != "" { + os.Setenv("myenv", s.environmentVariable) + } + results, err = treeNavigator.GetMatchingNodes(inputs, node) if err != nil { @@ -162,6 +167,13 @@ func documentInput(w *bufio.Writer, s expressionScenario) (string, string) { formattedDoc := "" formattedDoc2 := "" command := "eval" + + envCommand := "" + + if(s.environmentVariable != "") { + envCommand = fmt.Sprintf("myenv=\"%v\" ", s.environmentVariable) + } + if s.document != "" { if s.dontFormatInputForDoc { formattedDoc = s.document + "\n" @@ -188,14 +200,16 @@ func documentInput(w *bufio.Writer, s expressionScenario) (string, string) { } writeOrPanic(w, "then\n") + + if s.expression != "" { - writeOrPanic(w, fmt.Sprintf("```bash\nyq %v '%v' %v\n```\n", command, s.expression, files)) + writeOrPanic(w, fmt.Sprintf("```bash\n%vyq %v '%v' %v\n```\n", envCommand, command, s.expression, files)) } else { - writeOrPanic(w, fmt.Sprintf("```bash\nyq %v %v\n```\n", command, files)) + writeOrPanic(w, fmt.Sprintf("```bash\n%vyq %v %v\n```\n", envCommand, command, files)) } } else { writeOrPanic(w, "Running\n") - writeOrPanic(w, fmt.Sprintf("```bash\nyq %v --null-input '%v'\n```\n", command, s.expression)) + writeOrPanic(w, fmt.Sprintf("```bash\n%vyq %v --null-input '%v'\n```\n", envCommand, command, s.expression)) } return formattedDoc, formattedDoc2 } diff --git a/pkg/yqlib/path_tokeniser.go b/pkg/yqlib/path_tokeniser.go index 6afac412..20f77fdd 100644 --- a/pkg/yqlib/path_tokeniser.go +++ b/pkg/yqlib/path_tokeniser.go @@ -178,6 +178,25 @@ func stringValue(wrapped bool) lex.Action { } } +func envOp(strenv bool) lex.Action { + return func(s *lex.Scanner, m *machines.Match) (interface{}, error) { + value := string(m.Bytes) + + if strenv { + // strenv( ) + value = value[7:len(value)-1] + } else { + //env( ) + value = value[4:len(value)-1] + } + + envOperation := CreateValueOperation(value, value) + envOperation.OperationType = EnvOp + + return &Token{TokenType: OperationToken, Operation: envOperation}, nil + } +} + func nullValue() lex.Action { return func(s *lex.Scanner, m *machines.Match) (interface{}, error) { return &Token{TokenType: OperationToken, Operation: CreateValueOperation(nil, string(m.Bytes))}, nil @@ -266,6 +285,7 @@ func initLexer() (*lex.Lexer, error) { lexer.Add([]byte(`~`), nullValue()) lexer.Add([]byte(`"[^"]*"`), stringValue(true)) + lexer.Add([]byte(`strenv\([^\)]+\)`), envOp(true)) lexer.Add([]byte(`\[`), literalToken(OpenCollect, false)) lexer.Add([]byte(`\]`), literalToken(CloseCollect, true))