How can i use asterisk(*) in command line arguments in groovy? - regex

Helo!
I've a groovy script with one argument. The argument has to be a regex pattern. I want to use an * in the argument, but always got: The syntax of the command is incorrect.
This is an example (opt.p is the pattern getting from the arg):
def map1 = [e:'pine___apple', f:'pineapple']
map1.each { entry ->
entry.value.find(~/$opt.p/) { match -> println entry.value}
}
I want to use the script from the command line in this way:
groovy test -p pine_*a
And I expect that the result will be:
pine___apple
pineapple
I tried these solutions and more, but nothing works:
pine_*a
"pine_*a"
'pine_*a'
pine_\*a
'pine_\*a'
"pine_\*a"
pine_'\*'a
pine_"\*"a
pine_'\\*'a
pine_"\\*"a
Somebody knows how to solve this problem?
Thanks a lot!
EDIT:
I use:
Groovy Version: 2.4.6 JVM: 1.7.0_45 Vendor: Oracle Corporation OS: Windows 7 And I also use CliBuilder:
def cli = new CliBuilder()
cli.with
{
p('pattern', args: 1, required: false)
}
def opt = cli.parse(args)

The following groovy script:
def map = [e:'pine___apple', f:'pineapple']
map.each { k, v ->
v.find(~/${args[0]}/) { println "key: $k, value: $v -> ${v.find(args[0])}" }
}
prints the following on invocation:
$ groovy test.groovy pine_*a
Checking key: e, value: pine___apple -> pine___a
Checking key: f, value: pineapple -> pinea
or to exclude one of the map entries:
$ groovy test.groovy "pine_{1,9}a"
key: e, value: pine___apple -> pine___a
Not sure what the issue with your script is. Maybe the handling of opts.p like one of the comments suggests.
edit 1:
an alternative CliBuilder syntax to the one mentioned by Tim Yates in his answer:
def opt = new CliBuilder().with {
p longOpt: 'pattern', args: 1
parse(args)
}
edit 2: solution
as this is marked as the accepted answer, I will add what ended up being the solution here (I have a comment on this below, but comments are not immediately obvious when browsing for the solution).
This issue was caused by a bug in the windows groovy distribution startgroovy.bat file (see separate stackoverflow thread) which is used to launch groovy. The problem is with windows execution and parameter handling and it occurs before the groovy program even starts executing. There is a fair chance this has been fixed in later versions of groovy so it might be worth a try to upgrade to the latest version. If not, the answer in the above thread should make it possible to fix startgroovy.bat.

Think it's the way you're capturing your opt
I assume you're using the CliBuilder
And I suspect you've missed the args: 1 from the definition of the p parameter
def opt = new CliBuilder().with {
it.p('pattern', args: 1)
parse(args)
}
def map1 = [e:'pine___apple', f:'pineapple']
map1.each { entry ->
entry.value.find(~/$opt.p/) { match -> println entry.value}
}
Works as you describe it should for me...

Related

Cannot get Maven Archetype requiredProperty validationRegex to work

I have an archetype and I am trying to add a new requiredProperty which should only allow one of two possible values: "hibernate" and "hibernate-reactive". In the archetype-metadata.xml, I have defined the property as shown below:
<requiredProperty key="quarkus_orm_selection">
<validationRegex><![CDATA[^(hibernate|hibernate-reactive)$]]></validationRegex>
</requiredProperty>
In jshell and in other Java programs, I have verified that the regular expression works properly, but in the archetype when I test using a value like hibernate-ree the archetype proceeds without an error!
I proved out the regex as follows in JShell:
jshell> String[] examples = {"hibernate", "hibernate-reactive", "hibernate-re", "hibernate-ree", "testing", "reactive"}
examples ==> String[6] { "hibernate", "hibernate-reactive", "h ... ", "testing", "reactive" }
jshell> Pattern regex = Pattern.compile("^(hibernate|hibernate-reactive)$")
regex ==> ^(hibernate|hibernate-reactive)$
jshell> Arrays.asList(examples).stream().filter(i -> regex.matcher(i).matches()).forEach(System.out::println)
hibernate
hibernate-reactive
Can anyone suggest what I might be doing wrong?
I am using Maven Archetype Plugin version 3.2.0
As far as I can tell maven archetypes only validates reg-ex's if you pass in the property in interactive mode.
I created a archetype-post-generate.groovy script (see below)
src/main/resources/META-INF/archetype-post-generate.groovy:
String ormSelector = request.getProperties().get("quarkus_orm_selection")
def pattern = "^(hibernate|hibernate-reactive)\$" // the \$ is important!
final match = ormSelector.matches(pattern)
if (!match) {
println "[ERROR] ormSelector: $ormSelector is not valid"
println "[ERROR] please provide an ormSelector that follows this pattern: '$pattern'"
throw new RuntimeException("OrmSelector: $ormSelector is not valid")
}

JenkinsPipelineUnit helper can intercept text param call but not string param call

How can I get JenkinsPipelineUnit to intercept both text() and string() param calls? I have code that triggers a build with a few params. I want to write a nice unit test to check that it does what it should. However, the string() calls are not intercepted so I cannot test them. I can test the text() call.
Yes, it is possible to write unit tests for Jenkins pipeline code vs testing via jenkins production jobs. This project + shared libraries makes jenkins into a much better tool.
Any ideas on how I could do this? I looked in the JenkinsPipelineUnit project but didn't find an example that fit and couldn't figure out where to look in the runtime objects.
I do see that the project's BasePipelineTest.groovy links string to its stringInterceptor which seems to just eat it the string. Maybe, I can unregister theirs...
Example
def triggeringParams = [:]
....
for (def param in ['text', 'string']) {
helper.registerAllowedMethod(param, [LinkedHashMap],
{ LinkedHashMap data ->
triggeringParams << data
}
)
}
thisScript = helper.loadScript('''
package resources
return this''')
def params = []
params << thisScript.text(name: 'MULTILINE_PARAM', value: '\nline1\nline2')
params << thisScript.string(name: 'STRING_PARAM', value: 'a string')
thisScript.build(job: 'myJob', parameters: params)
println triggeringParams
Results
[
[name:JOB_PROPERTIES, value:
line1
line2]
]
Wrong type was the problem. The project's BasePipelineTest.groovy links string to its stringInterceptor which seems to just eat it the string and uses register Map not LinkedHashMap. So, the first is found before mine and boom, the string doesn't show in my collector.
If I modify my code to use the more generic map it works
void addParameterHelpers() {
for (def param in ['text', 'string']) {
helper.registerAllowedMethod(param, [Map],
{ LinkedHashMap data ->
triggeringParams << data
}
)
}
}

Exact field input mongoose for nodejs

I've recently been attempting to pull my hair out getting stuck on what I would call a trivial issue.
The way mongoose in nodejs handles the specific field inputs. I have a specific issue where mongoose is not doing the same as mongodb is doing.
The issue is the following, if I use a "-" symbol in my field name, mongoose seems to run some weird operation on it, instead of accepting it as part of a string.
I've tried running several regex commands, some / escapes, however it should literally just take the input, as I know the specific data I'm looking for.
The code causing the issue is the following:
datapoints.find({type: "charging-type", device: device._id})
.exec(function(err, objects){
if(!objects){
log("Can't find objects");
}
});
Going straight into mongo shell and typing:
db.datapoints.count({type: "charging-type", device: device._id})
taking out the type makes everything work, changing the type to for example: shuntvoltage, current, ... all work perfectly.
The problem thus occurs with the usage of this - symbol.
What would be the way to enter this inputstring with a special character as an exact string?
Any help would be much appreciated.
Edit as per request; I don't get any error, I get objects==undefined (or !objects), schema is below.
var datapointSchema = mongoose.Schema({
type: { type: String, lowercase: true},
value: { type: Number},
timestamp: { type: Number},
device: { type: ObjectId, ref: "devices"}
});
module.exports = mongoose.model('datapoints', datapointSchema)
Manually updated the field in mongodb from charging-status to chargingstatus, as no useful answer was produced.
It's a workaround and should be considered unresolved.
Final code ended up looking as such:
var cursor = calcpoints.find({device: device._id}).where('type').equals('chargingstatus').sort({timestamp: 1}).cursor();

jenkins workflow regex

I'm making my first steps in the Jenkins workflow (Jenkins ver 1.609.1)
I need to read a file, line by line, and then run regex on each line.
I'm interested in the regex "grouping" type, however "project" and "status" variables (the code below) get null value in Jenkins . Any suggestions what is wrong and how to fix it ?
def line = readFile (file)
def resultList = line.tokenize()
for(item in resultList ){
(item =~ /(\w+)=(\w+)$/).each { whole, project, status ->
println (whole)
println (project)
println (status)
}
}
each with a closure will not work: JENKINS-26481
If something using advanced language features works in standalone Groovy but not in Workflow, try just encapsulating it in a method marked #NonCPS. This will effectively run it as a “native” method. Only do this for code you are sure will run quickly and not block on I/O, since it will not be able to survive a Jenkins restart.
Well,
After checking out some other regex options I came around with the following solution that seems working :
def matcher = item =~ /(?<proj>\w+)=(?<status>\w+)/
if( matcher.matches() ) { etc...}

Call multiple webservices from play 2

I am a play2.0-Scala-beginner and have to call several Webservices to generate a HTML page.
After reading the The Play WS API page and a very interesting article from Sadek Drobi I am still unsure what's the best way to accomplish this.
The article shows some code snippets which I don't fully understand as a Play beginner.
Figure 2 on page 4:
val response: Either[Response,Response] =
WS.url("http://someservice.com/post/123/comments").focusOnOk
val responseOrUndesired: Either[Result,Response] = response.left.map {
case Status(4,0,4) => NotFound
case Status(4,0,3) => NotAuthorized
case _ => InternalServerError
}
val comments: Either[Result,List[Comment]] =
responseOrUndesired.right.map(r => r.json.as[List[Comment]])
// in the controller
comment.fold(identity, cs => Ok(html.showComments(cs)))
What does the last line with the fold do? Should comment be comments? Haven't I group the last statement in an Async block?
Figure 4 shows how to combine several IO calls with a single for-expression:
for {
profile <- profilePromise
events <- attachedEventsPromise
articles <- topArticlesPromise
} yield Json.obj(
"profile" -> profile,
"events" -> events,
"articles" -> articles )
}
// in the controller
def showInfo(...) = Action { rq =>
Async {
actorInfo(...).map(info => Ok(info))
}
}
How can I use this snippet? (I am a bit confused by the extra-} after the for-expression.)
Should I write something like this?
var actorInfo = for { // Model
profile <- profilePromise
events <- attachedEventsPromise
articles <- topArticlesPromise
} yield Json.obj(
"profile" -> profile,
"events" -> events,
"articles" -> articles )
def showInfo = Action { rq => // Controller
Async {
actorInfo.map(info => Ok(info))
}
}
What's the best way to combine the snippets from figure 2 and 4 (error handling + composition of IO non-blocking calls)? (f.ex. I want to produce a Error 404 status code if any of the called webservice produce an Error 404).
Maybe someone knows a complete example of calling webservices in the play framework (cannot find an example in the play Sample applications or anywhere else).
I have to say that the article is wrong in the example you show in Figure 2. The method focusOnOk does not exist in Play 2.0. I assume the author of the article used a pre-release version of Play 2 then.
Regarding comment, yes it should be comments. The fold in the statement is operating on an Either. It takes 2 functions as parameters. The first is a function to apply if it is a left value. The second is a function to apply if it is a right value. A more detailed explanation can be found here: http://daily-scala.blogspot.com/2009/11/either.html
So what the line does is. If I have a left value (which meant I got an undesired response), apply the built-in identity function which just gives you back the value. If it has a right value (which means I got an OK response), make a new result that shows the comments somehow.
Regarding Async, it's not actually asynchronous. focusOnOk is a blocking function (a remnant from the old Java days of Play 1.x). But remember, that's not valid Play 2 code.
As for Figure 4, the trailing } is actually because it's a partial alternative of what's in Figure 3. Instead of the numerous promise flatMaps. You can do a for comprehension instead. Also, I think it should be userInfo(...).map instead of actorInfo(...).map.
The Play documentation you linked to actually already shows you a full example.
def feedTitle(feedUrl: String) = Action {
Async {
WS.url(feedUrl).get().map { response =>
Ok("Feed title: " + (response.json \ "title").as[String])
}
}
}
will get whatever is at feedUrl, and you map it to do something with the response which has a status field you can check to see if it was a 404 or something else.
To that end, the Figure 3 and 4 of your linked article should give you a starting point. So you'd have something like,
def getInfo(...) : Promise[String] = {
val profilePromise = WS.url(...).get()
val attachedEventsPromise = WS.url(...).get()
val topArticlesPromise = WS.url(...).get()
for {
profile <- profilePromise
events <- attachedEventsPromise
articles <- topArticlesPromise
} yield {
// or return whatever you want
// remember to change String to something else in the return type
profile.name
}
}
def showInfo(...) = Action { rq =>
Async {
getInfo(...).map { info =>
// convert your info to a Result
Ok(info)
}
}
}