I have stored an entire yaml file into a Map yamlConfig which i am able to print and check.
The Output when I run the code: yamlConfig.each{ k, v -> println "${k}:${v}" } is:
Host:localhost
Port:10000
application:[name:ABC, preferences:[UUID:d3f3278e, server:localhost:2222]]
services:[[name:XYZ, instances:1, start:true]]
dataSets:[[name:ABC], [name:XYZ]]
Now, I am trying to fetch a value from Map using following code:
println yamlConfig.get("services").getAt("name")
However, I am getting the value: [XYZ]. Instead I need the result as XYZ, without square brackets.
Yml file I am using:
Host: localhost
Port: 10000
application:
name: ABC
preferences:
UUID: d3f3278e
server: localhost:2222
services:
- name: XYZ
instances: 1
start: true
data:
- name: ABC
- name: XYZ
This is because of the - character placed before your name property. It makes the yaml parser treat what's inside the services section as an array.
When you ask for the name property doing yamlConfig['services']['name'] groovy gives you all the macthing properties of array items in the services array, and it can only return them in another array.
So either remove the - or use yamlConfig['services'][0]['name'].
yamlConfig.get("services")
return a list but not a service, therefore when you apply getAt to the returned list of services it returns a list of names.
yamlConfig.get("services").getAt('name')
actually does
yaml['services'].collect { it['name'] }
so in order to get a name of a certain service you need to do something like this:
println yaml['services'][0]['name']
Related
Team,
issue is that it is still appending those lines to needed_list that match the pattern defined in skip_list. Not sure if there is space or why it is not skipping them, ex: // or }
I have two files and I need to see if a string from each line in fileA is referred in file2.
For this, I am looping over all strings just before : in fileA and check against all lines in file2 and printing them and skipping those lines from being printed that are not used in file2.
But I am observing that some strings from skip_list are still being printed.
Please ignore what sort of files these are because these are manually created sample files to test code.
file1
package deploy
application: sonarqube: helm: values: {
sonarqube: {
namespace: "sonarqube"
deploymentType: "StatefulSet"
role: "server"
// There should not be more than 1 sonarqube instance connected to the same database. Please set this value to 1 or 0 (in case you need to scale down programmatically).
file2
metadata:
name: {{ .scanjob }}
namespace: {{ .Values.namespace }}
command: ls
deploy: deploymentType
type: role: server
code
class SearchIn():
skip_list = ['{','}','/','[]','[',']','//','#']
needed_list = []
def charts_files(self, args):
chart_name = args
self.local_path = Path(environ.get("HOME"))/chart_name/"templates"
self.files_list=listdir(local_path)
return self.files_list
def values(self, args):
self.charts_files(chart_name)
values = "values.cue"
with open(self.local_path/values, 'r') as v:
for aline in v:
trimmed_line=aline.strip().split(":",1)[0]
print(trimmed_line)
for aptrn in self.skip_list:
if aptrn in trimmed_line or aptrn is trimmed_line:
continue
else:
print("no pattern found")
print(trimmed_line)
if trimmed_line not in self.needed_list:
self.needed_list.append(trimmed_line)
print(self.needed_list)
co = SearchIn()
chart_name = input(r'Enter chart name:')
co.values(chart_name)
Output: some snip
}
no pattern found
}
['package deploy', 'application', 'sonarqube', 'namespace', 'deploymentType', 'role', '// There should not.....
..
..
expected output
needed_list should not contain any element from skip_list
}
['package deploy', 'application', 'sonarqube', 'namespace', 'deploymentType','role'....]
I have this issue
*********** codeception.yml ***************
paths:
tests: tests
output: tests/_output
data: tests/_data
support: tests/_support
envs: tests/_envs
actor_suffix: Tester
#amount customer per product
amountPerProduct: 1
wishCountry: 1
wishProduct: 0
I am using the param like this:
$countryIndex = Configuration::config()['wishCountry'];
but on the console I calling the test like this:
codecept run tests/acceptance/ChangeCest.php --env chrome --xml --html -o "wishProduct:55"
I get this error:
enter image description here
QUESTION: how can I override this config in Gitlab?
Thank you
Not entirely sure if this solves your problem but for Codeception v5 (also my current local version v4.2.1) the option is exploded with : , i.e. with an appended space. I notice in your screenshot the exception does show the key/value without the space in between, but you didn't specify which version of Codeception you're using.
From Config.php:
foreach ($configOptions as $option) {
$keys = explode(': ', $option);
// ^ notice the space here
if (count($keys) < 2) {
throw new \InvalidArgumentException('--override should have config passed as "key: value"');
}
https://github.com/Codeception/Codeception/blob/5.0/src/Codeception/Command/Shared/ConfigTrait.php
i find the answer to my problem.
I store the parameters in a new file params.yml
params.yml
parameters:
WISH_PRODUCT: 55
codeception.yml
params:
- params.yml
acceptance.suite.yml
config:
custom_params:
wishProduct: %WISH_PRODUCT%
AcceptanceTester.php
so in AcceptanceTester I can read the values like this
$custom_params = Configuration::suiteSettings('acceptance', Configuration::config())['modules']['custom_params'];
If I have a yaml file like this:
obj:
- name: 'msg'
patterns:
'("ssn":")([^"]*)(")' : '$1xxxxxxxxx$3'
'("cvv":")([^"]*)(")' : '$1xxxx$3'
'("ssn":")([^"]*)(")' : '$1xxxxxxxxx$3'
If I use the Groovy YamlSlurper class to load this, the "patterns" object will have two properties, with the following names:
("ssn":")([^"]*)(")
("cvv":")([^"]*)(")
The third property in the input has a name identical to the first property name, so the third one will override the first (or vice versa).
Is there any way I could use some combination of YamlSlurper and perhaps YamlBuilder to somehow detect that the input has a duplicate property name?
I can see that changing the expected syntax of this file so that it expects a format like this:
obj:
- name: 'msg'
patterns:
- '("ssn":")([^"]*)(")' : '$1xxxxxxxxx$3'
- '("cvv":")([^"]*)(")' : '$1xxxx$3'
- '("ssn":")([^"]*)(")' : '$1xxxxxxxxx$3'
Would give me the ability to detect duplicates. If I can't detect duplicate property names on the input using the original format, I will consider changing the spec to require the modified format.
behind groovy.yaml.YamlSlurper there is a jackson library.
YamlSlurper.parse()
-> YamlConverter.convertYamlToJson() -> jackson
so, you could use it to detect first duplicate:
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.DeserializationFeature
String yaml = '''
obj:
- name: 'msg'
patterns:
'("ssn":")([^"]*)(")' : '$1xxxxxxxxx$3'
'("cvv":")([^"]*)(")' : '$1xxxx$3'
'("ssn":")([^"]*)(")' : '$1xxxxxxxxx$3'
'''
def result =
new ObjectMapper()
.enable(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY)
.readTree(new YAMLFactory().createParser(yaml))
this code throws exception:
com.fasterxml.jackson.databind.exc.MismatchedInputException:
Duplicate field '("ssn":")([^"]*)(")' for `ObjectNode`:
not allowed when `DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY` enabled
at [Source: (StringReader); line: 7, column: 31]
I have some output from a call to a backend server (DSDB) using the unix shell .execute command in groovy. What it gives me is a list of key value pairs separated by a line and each pair separated by a colon. I need to have each Key Value pair placed into a map. This is the output I receive:
Group Name: groupName
GID: 12345
Type: 1
Comments:
Visibility: visibile1
Owner Name: name1
Owner Number: 123
Manager Name: manager1
Manager Number: 234
Environment: dev
State: 0
I need to get the value of Owner Name within a function and pass it back as a variable and I also need the value of environment in another function. These will be two separate functions.
Couldn't find a regex that would do all of that, but a bit of groovy fixes that:
final data = """
Group Name: groupName
GID: 12345
Type: 1
Comments:
Visibility: visibile1
Owner Name: name1
Owner Number: 123
Manager Name: manager1
Manager Number: 234
Environment: dev
State: 0
"""
final a = (data =~ /\s*([^:]+):(.*)/)
.collect { [it[1], it[2].trim()] }
.collectEntries()
assert a["Owner Name"] == "name1"
assert a["Environment"] == "dev"
Java patterns are in "single line mode" by default. This regex is matching keys and values separated by colon and finds a match for each line.
The collect then maps the matches into tuples. I'm also abusing this step to strip the leading space from the values (except from "Comments" field, which doesn't have a value).
Finally, collectEntries can be used to map the list of tuples into a single map.
I'm trying to use the groovy CliBuilder to parse command line options. I'm trying to use multiple long options without a short option.
I have the following processor:
def cli = new CliBuilder(usage: 'Generate.groovy [options]')
cli.with {
h longOpt: "help", "Usage information"
r longOpt: "root", args: 1, type: GString, "Root directory for code generation"
x args: 1, type: GString, "Type of processor (all, schema, beans, docs)"
_ longOpt: "dir-beans", args: 1, argName: "directory", type: GString, "Custom location for grails bean classes"
_ longOpt: "dir-orm", args: 1, argName: "directory", type: GString, "Custom location for grails domain classes"
}
options = cli.parse(args)
println "BEANS=${options.'dir-beans'}"
println "ORM=${options.'dir-orm'}"
if (options.h || options == null) {
cli.usage()
System.exit(0)
}
According to the groovy documentation I should be able to use multiple "_" values for an option when I want it to ignore the short option name and use a long option name only. According to the groovy documentation:
Another example showing long options (partial emulation of arg
processing for 'curl' command line):
def cli = new CliBuilder(usage:'curl [options] <url>')
cli._(longOpt:'basic', 'Use HTTP Basic Authentication')
cli.d(longOpt:'data', args:1, argName:'data', 'HTTP POST data')
cli.G(longOpt:'get', 'Send the -d data with a HTTP GET')
cli.q('If used as the first parameter disables .curlrc')
cli._(longOpt:'url', args:1, argName:'URL', 'Set URL to work with')
Which has the following usage message:
usage: curl [options] <url>
--basic Use HTTP Basic Authentication
-d,--data <data> HTTP POST data
-G,--get Send the -d data with a HTTP GET
-q If used as the first parameter disables .curlrc
--url <URL> Set URL to work with
This example shows a common convention. When mixing short and long
names, the short names are often one
character in size. One character
options with arguments don't require a
space between the option and the
argument, e.g. -Ddebug=true. The
example also shows the use of '_' when
no short option is applicable.
Also note that '_' was used multiple times. This is supported but
if any other shortOpt or any longOpt is repeated, then the behavior is undefined.
http://groovy.codehaus.org/gapi/groovy/util/CliBuilder.html
When I use the "_" it only accepts the last one in the list (last one encountered). Am I doing something wrong or is there a way around this issue?
Thanks.
not sure what you mean it only accepts the last one. but this should work...
def cli = new CliBuilder().with {
x 'something', args:1
_ 'something', args:1, longOpt:'dir-beans'
_ 'something', args:1, longOpt:'dir-orm'
parse "-x param --dir-beans beans --dir-orm orm".split(' ')
}
assert cli.x == 'param'
assert cli.'dir-beans' == 'beans'
assert cli.'dir-orm' == 'orm'
I learned that my original code works correctly. What is not working is the function that takes all of the options built in the with enclosure and prints a detailed usage. The function call built into CliBuilder that prints the usage is:
cli.usage()
The original code above prints the following usage line:
usage: Generate.groovy [options]
--dir-orm <directory> Custom location for grails domain classes
-h,--help Usage information
-r,--root Root directory for code generation
-x Type of processor (all, schema, beans, docs)
This usage line makes it look like I'm missing options. I made the mistake of not printing each individual item separate from this usage function call. That's what made this look like it only cared about the last _ item in the with enclosure. I added this code to prove that it was passing values:
println "BEANS=${options.'dir-beans'}"
println "ORM=${options.'dir-orm'}"
I also discovered that you must use = between a long option and it's value or it will not parse the command line options correctly (--long-option=some_value)