Better way to skip comments in a file parsing - regex

At the moment I use
<file>.eachLine { line ->
if (line ==~ /^#.*$/) {
return // skip comments
}
}
Is there an easier way?

Are you trying to separate the test for comments from the rest of the code in your closure?
You could do this, for some File 'f'....
f.filterLine( { it ==~ /^[^#].*/ } ).each { < process non-comments > }

Related

Groovy script for scriptrunner

I am currently working on a Scriptrunner script that has the objectives of rejecting push if the user pushes a not freeze dependancies. The script itself is not really hard but I don't know how to use Scriptrunner well enough to make it work, any advices ?
I tried several ways to make my script work, here is the script as it is right now :
def regex = ".*requires\\(\"[^\\d|_|\\-](\\S)+/\\[(\\d)(\\.\\d)*\\]#(eca|exail)/stable\""
def fileName = "conanfile.py"
def file = new File(fileName)
if (file.exists()) {
file.readLines().each { line ->
if (line.startsWith("self.requires")) {
if (!(line =~ regex)) {
log.error("Error: Freeze your dependancies")
return false
}
}
}
// log.info("All 'self.requires' lines match the regex.")
return true
} else {
//log.error("Error: $fileName does not exist.")
return true
}
as you can see it is pretty simple, we check if there is a file named "conanfile.py", and read it to find a line starting with "self.requires" and compare the line with our Regex ( the double \ is because of groovy). I am quite lost on how to make it works on Scriptrunner.

Prettier putting if statement on one line

Prettier formats if statement without curley braces into one line.
This means that this :
function getErrorMessage(response) {
let errorMessage = null;
if (!response.originalError.response)
errorMessage = 'network error';
else
errorMessage = response.originalError.response.data.errorMessage;
return errorMessage;
}
becomes this :
function getErrorMessage(response) {
let errorMessage = null;
if (!response.originalError.response) errorMessage = 'network error';
else errorMessage = response.originalError.response.data.errorMessage;
return errorMessage;
}
which is FAR more unreadable.
Is there a way of disabling this?
As asked in a similar question, it turns out that the answer is that you can not and will not be able to.
As for the WFT that an average senses, well... Apparently, opinionated doesn't mean respected and well-considered in opinion of many. It means that it's implementing the author's opinion.
So, surprisingly, the unexpected thing isn't the lack of configurability but rather that there are any options to be set at all! Go figure... Someone should create a new package called EvenPrettier or FexiblyPrettier and fork in more options. If I only knew how, I'd do it.
I finally ended up using Beautify - HookyQR extension for vscode
https://marketplace.visualstudio.com/items?itemName=HookyQR.beautify
Example Settings
File: .jsbeautifyrc
{
"brace_style": "collapse,preserve-inline",
"max_preserve_newlines": 2,
"end_with_newline": false
}
Example Code
File: a.js
function dfs(start) {
if (start > n)
return;
ans.push(start);
for (let i = 0; i <= 9; i++)
dfs(start * 10 + i);
}

CouchDB: View to return only certain documents?

I have (tried) to write a view to identify documents with an "otherCauseForRelease" attribute AND that attribute is actually populated. My View code is:
function (doc) {
if(doc.payload.otherCauseForRelease.length > 5); emit(doc.payload.otherCauseForRelease);
}
However, the return set includes documents with attribute values like "" (an open double-quotation followed by a close double-quotation). How can I exclude these documents from my results?
Try with this one here :
function (doc) {
if(doc.payload.otherCauseForRelease.length > 5)
emit(doc.payload.otherCauseForRelease);
}
You basically add an extra ; at the end of your if. Doing so, it didn't consider the next statement as the body of the if.
Another example with curly braces:
function (doc) {
if(doc.payload.otherCauseForRelease.length > 5){
emit(doc.payload.otherCauseForRelease);
}
}

How to parse multiline records in groovy?

I have log file containing somewhere five * in two places. The file can be big.
Log record
*****
Log record
Log record
*****
Log record
I would like to get everything which is between five *. Right, I can read line by line but perhaps there are better solutions like parsing using Regular Expressions in Groovy?
Thank you.
You could also write a custom Reader like:
class DelimitedReader extends BufferedReader {
String delimiterLine
DelimitedReader( String delimiterLine, Reader reader ) {
super( reader )
this.delimiterLine = delimiterLine
scanUntilDelimiter()
}
private scanUntilDelimiter() {
String line = super.readLine()
while( line != null && line != delimiterLine ) {
line = super.readLine()
}
}
String readLine() {
String line = super.readLine()
if( line == delimiterLine ) {
line = null
}
line
}
}
And then, you can do something like this to iterate over them
new File( '/tmp/test.txt' ).withReader { r ->
new DelimitedReader( '*****', r ).eachLine { line ->
println line
}
}
This saves you having the whole file loaded in to a single (potentially huge) string
Try this regex:
(?s)(?<=[*]{5}).+(?=[*]{5})
Demo
http://groovyconsole.appspot.com/script/2405001
This regex matches everything between the first ***** and the next one:
(?<=\*{5})[\s\S]*(?=\*{5})

Parsing xml and dump in file each <> block

I am trying to parse xml with some simple C++ which has blocks like
<mgrwt event="1">
...
...
...
</mgrwt>
<mgrwt event="2">
...
...
...
</mgrwt>
Now, I have a bash script which acts on each of these blocks - So, my question is, how can I loop inside the xml ( I do not need RapidXML or something similar though) so that to easily dump to a small temp file each block ?
My parser looks like
bool begin_tag = false;
while (getline(in,line))
{
std::string tmp;
tmp=line;
if(line.find("<mgrwt event=")<=line.size()){
cout<<line<<endl;
begin_tag = true;
continue;
}
else if (tmp == "</mgrwt>")
{
begin_tag = false;
}
}
}
thanks
Alex
I would recommend using an XML parser for reading XML files. Checkout expat, POCO XML or other libraries.
If you can't for whatever reason, and the stuff you're reading always looks exactly the same as in your sample with no other formatting variations, you also should use find() to detect the end of the block:
else if(line.find("</mgrwt>")<=line.size())
{
begin_tag = false;
}