I have a string like "AAA_revision12" and I have to extract the substring before "_" for example "AAA". I tried some regexps, but they doesn't work in jenkins.
String stringParser(String inputString) {
inputString ? inputString.split(/_\d/)[0] : ''
}
$string = "AAA revision".split('-')
assert string[0]
Your question is very confusing. I presume you are after a groovy snippet which will return the substring. If so:
String stringParser(String inputString) {
inputString.split("_")[0]
}
As an example:
String input = "foo_bar"
desired = "foo"
assert desired == stringParser(input)
> True
Related
I'd like to extraxt string "test", which is the letters before "#",by using RegExp like following, but actually could get "test#" including "#".
How can I get only "test" without "#" ?
final getPass = "test#example.com";
final regEx = RegExp(r'(.+?)#');
print(regEx.firstMatch(getPass)?.group(0));
If using a Regexp is not mandatory for you, you could use String methods :
final getPass = "test#example.com";
print(getPass.split("#").first);
Use .group(1)
final getPass = "test#example.com";
final regEx = RegExp(r'(.+?)#');
print(regEx.firstMatch(getPass)?.group(1));
I would like to check if a string contains any of the following symbols ^ $ * . [ ] { } ( ) ? - " ! # # % & / \ , > < ' : ; | _ ~ ` + =
I tried using the following
string.contains(RegExp(r'[^$*.[]{}()?-"!##%&/\,><:;_~`+=]'))
But that does not seem to do anything. I am also not able to add the ' symbol.
Questions:
How do I check if a string contains any one of a set of symbols?
How do I add the ' symbol in my regex collection?
When writing such a RegExp pattern, you should escape the special symbols (if you want to search specifically by them).
Also, to add the ' to the RegExp, there is no straightforward way, but you could use String concatenation to work around this.
This is what the final result could look like:
void main() {
final regExp = RegExp(
r'[\^$*.\[\]{}()?\-"!##%&/\,><:;_~`+=' // <-- Notice the escaped symbols
"'" // <-- ' is added to the expression
']'
);
final string1 = 'abc';
final string2 = 'abc[';
final string3 = "'";
print(string1.contains(regExp)); // false
print(string2.contains(regExp)); // true
print(string3.contains(regExp)); // true
}
To ad both ' an " to the same string literal, you can use a multiline (triple-quoted) string.
string.contains(RegExp(r'''[^$*.[\]{}()?\-"'!##%&/\\,><:;_~`+=]'''))
You also need to escape characters which have meaning inside a RegExp character class (], - and \ in particular).
Another approach is to create a set of character codes, and check if the string's characters are in that set:
var chars = r'''^$*.[]{}()?-"'!##%&/\,><:;_~`+=''';
var charSet = {...chars.codeUnits};
var containsSpecialChar = string.codeUnits.any(charSet.contains);
I am trying to generate some generic Groovy code for Jenkins but I seem to have trouble with multi line strings and extra white space. I've tried everything I could find by Googling but I can't seem to get it working.
My issue isn't related to simple multi line strings. I managed to trim white space by using the stripIndent() and stripMargin() methods for simple cases. My issue is caused by having interpolated methods inside my strings.
Groovy info: Groovy Version: 3.0.2 JVM: 13.0.2 Vendor: Oracle Corporation OS: Mac OS X
String method2(String tier, String jobName) {
return """
Map downstreamJobs = [:]
stage ("${jobName}-${tier}-\${region}_${jobName}") {
test
}
""".stripIndent().stripMargin()
}
static String simpleLog() {
return """
script {
def user = env.BUILD_USER_ID
}
""".stripIndent().stripMargin()
}
static String method1() {
return """\
import jenkins.model.Jenkins
currentBuild.displayName = "name"
${simpleLog()}
""".stripIndent().stripMargin()
}
String generateFullDeploymentPipelineCode() {
return """Text here
${method1()}
${method2("test1", "test2")}
""".stripIndent().stripMargin()
}
println(generateFullDeploymentPipelineCode())
This is what it prints(or writes to disk):
Text here
import jenkins.model.Jenkins
currentBuild.displayName = "name"
script {
def user = env.BUILD_USER_ID
}
Map downstreamJobs = [:]
stage ("test2-test1-${region}_test2") {
test
}
Why the extra space around the import lines? I know the indentation method is supposed to trim all white space according to the least number of leading spaces, so that's why we use backslash (example here https://stackoverflow.com/a/19882917/7569335).
That works for simple strings, but it breaks down once use start using interpolation. Not with regular variables, just when you interpolate an entire method.
as variant - use just stripMargin() and only once on a final string
String method2(String tier, String jobName) {
return """\
|Map downstreamJobs = [:]
|stage ("${jobName}-${tier}-\${region}_${jobName}") {
| test
|}
"""
}
static String simpleLog() {
return """\
|script {
| def user = env.BUILD_USER_ID
|}
"""
}
static String method1() {
return """\
|import jenkins.model.Jenkins
|currentBuild.displayName = "name"
${simpleLog()}
"""
}
String generateFullDeploymentPipelineCode() {
return """\
|Text here
${method1()}
${method2("test1", "test2")}
""".stripIndent().stripMargin()
}
println(generateFullDeploymentPipelineCode())
result:
Text here
import jenkins.model.Jenkins
currentBuild.displayName = "name"
script {
def user = env.BUILD_USER_ID
}
Map downstreamJobs = [:]
stage ("test2-test1-${region}_test2") {
test
}
another variant with trim() and stripIndent()
def method2(String tier, String jobName) {
return """
Map downstreamJobs = [:]
stage ("${jobName}-${tier}-\${region}_${jobName}") {
test
}
""".trim()
}
def simpleLog() {
return """
script {
def user = env.BUILD_USER_ID
}
""".trim()
}
def method1() {
return """
import jenkins.model.Jenkins
currentBuild.displayName = "name"
${simpleLog()}
""".trim()
}
def generateFullDeploymentPipelineCode() {
return """\
Text here
${method1()}
${method2("test1", "test2")}
""".stripIndent()
}
println(generateFullDeploymentPipelineCode())
When you insert a string through interpolation you only indent the first line of it. The following lines of the inserted string will be indented differently, which messes everything up.
Using some lesser-known members of GString (namely .strings[] and .values[]), we can align the indentation of all lines of each interpolated value.
String method2(String tier, String jobName) {
indented """
Map downstreamJobs = [:]
stage ("${jobName}-${tier}-\${region}_${jobName}") {
test
}
"""
}
String simpleLog() {
indented """\
script {
def user = env.BUILD_USER_ID
}
"""
}
String method1() {
indented """\
import jenkins.model.Jenkins
currentBuild.displayName = "name"
${simpleLog()}
"""
}
String generateFullDeploymentPipelineCode() {
indented """\
Text here
${method1()}
${method2("test1", "test2")}
"""
}
println generateFullDeploymentPipelineCode()
//---------- Move the following code into its own script ----------
// Function to adjust the indentation of interpolated values so that all lines
// of a value match the indentation of the first line.
// Finally stripIndent() will be called before returning the string.
String indented( GString templ ) {
// Iterate over the interpolated values of the GString template.
templ.values.eachWithIndex{ value, i ->
// Get the string preceding the current value. Always defined, even
// when the value is at the beginning of the template.
def beforeValue = templ.strings[ i ]
// RegEx to match any indent substring before the value.
// Special case for the first string, which doesn't necessarily contain '\n'.
def regexIndent = i == 0
? /(?:^|\n)([ \t]+)$/
: /\n([ \t]+)$/
def matchIndent = ( beforeValue =~ regexIndent )
if( matchIndent ) {
def indent = matchIndent[ 0 ][ 1 ]
def lines = value.readLines()
def linesNew = [ lines.head() ] // The 1st line is already indented.
// Insert the indentation from the 1st line into all subsequent lines.
linesNew += lines.tail().collect{ indent + it }
// Finally replace the value with the reformatted lines.
templ.values[ i ] = linesNew.join('\n')
}
}
return templ.stripIndent()
}
// Fallback in case the input string is not a GString (when it doesn't contain expressions)
String indented( String templ ) {
return templ.stripIndent()
}
Live Demo at codingground
Output:
Text here
import jenkins.model.Jenkins
currentBuild.displayName = "name"
script {
def user = env.BUILD_USER_ID
}
Map downstreamJobs = [:]
stage ("test2-test1-${region}_test2") {
test
}
Conclusion:
Using the indented function, a clean Groovy syntax for generating code from GString templates has been achieved.
This was quite a learning experience. I first tried to do it completely different using the evaluate function, which turned out to be too complicated and not so flexible. Then I randomly browsed through some posts from mrhaki blog (always a good read!) until I discovered "Groovy Goodness: Get to Know More About a GString". This was the key to implementing this solution.
I have csv file containing some data like:
374,Test Comment multiplelines \n Here's the 2nd line,Other_Data
Where 374 is the object ID from doors, then some commentary and then some other data.
I have a piece of code that reads the data from the CSV file, stores it in the appropriate variables and then writes it to the doors Object.
Module Openend_module = edit("path_to_mod", true,true,true)
Object o ;
Column c;
string attrib;
string oneLine ;
string OBJECT_ID = "";
string Comment = "";
String Other_data = "";
int offset;
string split_text(string s)
{
if (findPlainText(s, sub, offset, len, false))
{
return s[0 : offset -1]
}
else
{
return ""
}
}
Stream input = read("Path_to_Input.txt");
input >> oneLine
OBJECT_ID = split_text(oneLine)
oneLine = oneLine[offset+1:]
Comment = split_text(oneLine)
Other_data = oneLine[offset+1:]
When using print Comment the output in the DXL console is : Test Comment multiplelines \n Here's the 2nd line
for o in Opened_Module do
{
if (o."Absolute Number"""==OBJECT_ID ){
attrib = "Result_Comment " 2
o.attrib = Comment
}
}
But after writing to the doors object, the \n is not taken into consideration and the result is as follows:
I've tried putting the string inside a Buffer and using stringOf() but the escape character just disappeared.
I've also tried adding \r\n and \\n to the input csv text but still no luck
This isn't the most efficient way of handling this, but I have a relatively straightforward fix.
I would suggest adding the following:
Module Openend_module = edit("path_to_mod", true,true,true)
Object o ;
Column c;
string attrib;
string oneLine ;
string OBJECT_ID = "";
string Comment = "";
String Other_data = "";
int offset;
string split_text(string s)
{
if (findPlainText(s, sub, offset, len, false))
{
return s[0 : offset -1]
}
else
{
return ""
}
}
Stream input = read("Path_to_Input.txt");
input >> oneLine
OBJECT_ID = split_text(oneLine)
oneLine = oneLine[offset+1:]
Comment = split_text(oneLine)
Other_data = oneLine[offset+1:]
//Modification to comment string
int x
int y
while ( findPlainText ( Comment , "\\n" , x , y , false ) ) {
Comment = ( Comment [ 0 : x - 1 ] ) "\n" ( Comment [ x + 2 : ] )
}
This will run the comment string through a parser, replacing string "\n" with the char '\n'. Be aware- this will ignore any trailing spaces at the end of a line.
Let me know if that helps.
I'm working on a DXL program in Doors which supposed to output to a csv file all of source module, target, linkset and version of each (source/target) modules. I've succeed to output "source module, target, linkset but I couldn't extract the version of modules. Does anyone know how to do it ?
Here is my code bellow:
The following uses an output file which is in C:\Temp, but you can easily change that.
it works by matching modules using a grep string, again which you can change to suit.
I have different module types, and therefore I can just get the results on the prefix 'STR' in this case. I decided to have multiple scripts for different prefix modules, rather than dynamically pass the STR keyword.
You need to enter your folder and subfolders for the "modPathname"
then adjust the Regexp "GrepString" to suit your naming convention
alternatively you can bypass all this by hardcoding the values.
string filename = "C:\\TEMP\\STR_Baseline_Info.txt"
Stream outFile = write filename
string Modtype = "STR"
void PrintAndOutput ( string s)
{
// print (s) // Enable if you want output
outFile << s
}
void DisplayResults( string Modtype )
{
Item modItem
Module mName
Regexp GrepString = regexp2 "^" Modtype "-[0-8][0-9][0-9]"
Folder modPathname = folder "/EnterYourFolderHere/AnySubFolders/" Modtype ""
string fullModuleName , CommentStr , moduleName
Baseline b
PrintAndOutput "------------------------------------------------------------------------------\n"
CommentStr = "This File is automatically produced via the " Modtype " Baseline Info.dxl script. \n" Modtype " Versions as of : " dateAndTime(today) "\n"
PrintAndOutput CommentStr
PrintAndOutput "-------------------------------------------------------------------------------\n\n"
for modItem in modPathname do
{
if (type (modItem ) == "Formal")
{
moduleName = (name modItem)
if (GrepString moduleName)
{
fullModuleName = (fullName(modItem))
mName = read(fullName modItem , false)
b= getMostRecentBaseline (mName)
if (b != null )
{
PrintAndOutput moduleName " -\tBaseline : "(major b)"."(minor b)(suffix b) " \t " (dateOf b) "\n"
}
else
{
PrintAndOutput moduleName " \t### No Baseline Information ### \t" " \n"
}
}
}
}
}
DisplayResults ( Modtype)