I've created file GroovyAnsi.groovy and code is below:
Source is https://gist.github.com/tvinke/db4d21dfdbdae49e6f92dcf1ca6120de
Now, please help me to call this function in my jenkins groovy script to color the output..
i could not use this function as i'm getting below error:
groovy.lang.MissingPropertyException: No such property: out for class: groovy.lang.Binding
at groovy.lang.Binding.getVariable(Binding.java:63)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:270)
// Ansi colors in Groovy
// Author: Ted Vinke
import static Ansi.*
println color("BOLD", Ansi.BOLD)
println color("ITALIC", Ansi.ITALIC)
println color("UNDERLINE", Ansi.UNDERLINE)
println color("BLINK", Ansi.BLINK)
println color("RAPID_BLINK", Ansi.RAPID_BLINK)
println color("REVERSE_VIDEO", Ansi.REVERSE_VIDEO)
println color("INVISIBLE_TEXT", Ansi.INVISIBLE_TEXT)
println color("RED", Ansi.RED)
println color("BLACK", Ansi.BLACK)
println color("BOLD", Ansi.BOLD)
println color("GREEN", Ansi.GREEN)
println color("YELLOW", Ansi.YELLOW)
println color("BLUE", Ansi.BLUE)
println color("MAGENTA", Ansi.MAGENTA)
println color("CYAN", Ansi.CYAN)
println color("WHITE", Ansi.WHITE)
println color("DARK_GRAY", Ansi.DARK_GRAY)
println color("LIGHT_BLUE", Ansi.LIGHT_BLUE)
println color("LIGHT_GREEN", Ansi.LIGHT_GREEN)
println color("LIGHT_CYAN", Ansi.LIGHT_CYAN)
println color("LIGHT_RED", Ansi.LIGHT_RED)
println color("LIGHT_PURPLE", Ansi.LIGHT_PURPLE)
println color("LIGHT_YELLOW", Ansi.LIGHT_YELLOW)
println(
[
'Look', Ansi.LIGHT_RED,
'ma', Ansi.REVERSE_VIDEO,
',', Ansi.GREEN,
'no ', Ansi.MAGENTA,
'hands!', Ansi.LIGHT_YELLOW
]
.collate(2)
.collect { pair ->
color(pair.first(), pair.last())
}.join(' ')
)
/**
* Small ANSI coloring utility.
*
* #see http://www.bluesock.org/~willg/dev/ansi.html
* #see https://gist.github.com/dainkaplan/4651352
*/
class Ansi {
static final String NORMAL = "\u001B[0m"
static final String BOLD = "\u001B[1m"
static final String ITALIC = "\u001B[3m"
static final String UNDERLINE = "\u001B[4m"
static final String BLINK = "\u001B[5m"
static final String RAPID_BLINK = "\u001B[6m"
static final String REVERSE_VIDEO = "\u001B[7m"
static final String INVISIBLE_TEXT = "\u001B[8m"
static final String BLACK = "\u001B[30m"
static final String RED = "\u001B[31m"
static final String GREEN = "\u001B[32m"
static final String YELLOW = "\u001B[33m"
static final String BLUE = "\u001B[34m"
static final String MAGENTA = "\u001B[35m"
static final String CYAN = "\u001B[36m"
static final String WHITE = "\u001B[37m"
static final String DARK_GRAY = "\u001B[1;30m"
static final String LIGHT_RED = "\u001B[1;31m"
static final String LIGHT_GREEN = "\u001B[1;32m"
static final String LIGHT_YELLOW = "\u001B[1;33m"
static final String LIGHT_BLUE = "\u001B[1;34m"
static final String LIGHT_PURPLE = "\u001B[1;35m"
static final String LIGHT_CYAN = "\u001B[1;36m"
static String color(String text, String ansiValue) {
ansiValue + text + NORMAL
}
}
You must provide your class Ansi to the Jenkins classpath. You could create a jar with Ansi class and copy this jar in the Jenkins classpath or you must declare Ansi class in each groovy script that you use in Jenkins.
Related
I'm very new to MapReduce and was learning about the implementation of the setup method. The new string value given by configuration is printing correctly but when I tried to further process it, the initial value of the string comes in action. I know the string is immutable, but it should provide the value currently pointing to, to other methods.
public class EMapper extends Mapper<LongWritable, Text, Text, Text> {
String wordstring = "abcd"; //initialized wordstring with "abcd"
public void setup(Context context) {
Configuration config = new Configuration(context.getConfiguration());
wordstring = config.get("mapper.word"); // As string is immutable,
// wordstring should now point to
// value given by mapper.word
//Here mapper.word="ankit" by
//using -D in hadoop command
}
String def = wordstring;
String jkl = String.valueOf(wordstring); //tried to copy current value
//but
//string jkl prints the initial
/value.
public void map(LongWritable key, Text value, Context context)
throws InterruptedException, IOException {
context.write(new Text("wordstring=" + wordstring + " " + "def=" +
def),
new Text("jkl=" + jkl));
}
}
public class EDriver extends Configured implements Tool {
private static Logger logger = LoggerFactory.getLogger(EDriver.class);
public static void main(String[] args) throws Exception {
logger.info("Driver started");
int res = ToolRunner.run(new Configuration(), new EDriver(), args);
System.exit(res);
}
public int run(String[] args) throws Exception {
if (args.length != 2) {
System.err.printf("Usage: %s needsarguments",
getClass().getSimpleName());
return -1;
}
Configuration conf = getConf();
Job job = new Job(conf);
job.setJarByClass(EDriver.class);
job.setJobName("E Record Reader");
job.setMapperClass(EMapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Text.class);
job.setReducerClass(EReducer.class);
job.setNumReduceTasks(0);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(NullWritable.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
job.setInputFormatClass(ExcelInputFormat.class);
return job.waitForCompletion(true) ? 0 : 1;
}
}
I expected output to be
wordstring=ankit def=ankit jkl=ankit
Actual output is
wordstring=ankit def=abcd jkl=abcd
This has nothing to do with the mutability of Strings, and everything to do with code execution order.
Your setup method will only be called after any class-level commands are executed. The order you write the code doesn't change anything. If you were to re-write the top section of your code in the order that it actually executes, you'd have:
public class EMapper extends Mapper<LongWritable, Text, Text, Text> {
String wordstring = "abcd";
String jkl = String.valueOf(wordstring);
public void setup(Context context) {
Configuration config = new Configuration(context.getConfiguration());
wordstring = config.get("mapper.word"); //By the time this is called, jkl has already been assigned to "abcd"
}
So it's not surprising that jkl is still abcd. You should set jkl within the setup method, like so:
public class EMapper extends Mapper<LongWritable, Text, Text, Text> {
String wordstring;
String jkl;
public void setup(Context context) {
Configuration config = new Configuration(context.getConfiguration());
wordstring = config.get("mapper.word");
jkl = wordstring;
//Here, jkl and wordstring are both different variables pointing to "ankit"
}
//Here, jkl and wordstring are null, as setup(Context context) has not yet run
public void map(LongWritable key, Text value, Context context)
throws InterruptedException, IOException {
//Here, jkl and wordstring are both different variables pointing to "ankit"
context.write(new Text("wordstring=" + wordstring),
new Text("jkl=" + jkl));
}
Of course you don't actually need jkl, you can just directly use wordstring.
The problem has been solved. Actually, I was running Hadoop in the distributed mode where SETUP, MAPPER, REDUCER, and CLEANUP run on different JVMs. So, data cannot be transported from SETUP to MAPPER directly. The first wordstring object was initialized to "abcd" in mapper. I tried to change the wordstring in SETUP(another object of wordstring was created) which was actually taking place in another JVM.
So, when I tried to copy the "wordstring" in jkl at
String jkl = String.valueOf(wordstring);
the first value of wordstring(the one created by mapper &initialized to "abcd") was being copied to jkl.
If I run Hadoop in standalone mode, it will use a single JVM and the value given to wordstring by SETUP would have been copied to jkl.
Thus, jkl got the copy of wordstring initialized to "abcd" and not the one given by SETUP.
I used
HashMap map=new HashMap();
to transport data between SETUP to MAPPER, and then jkl got a copy of value given by wordstring of SETUP.
I am loading a groovy script and I need the following class:
import java.util.function.Function
import java.util.function.Supplier
class MaskingPrintStream extends PrintStream {
private final Function<String,String> subFunction
private final Supplier<String> secretText
public MaskingPrintStream(PrintStream out, Supplier<String> secretText, Function<String,String> subFunction) {
super(out);
this.subFunction = subFunction;
this.secretText = secretText;
}
#Override
public void write(byte b[], int off, int len) {
String out = new String(b,off,len);
String secret = secretText.get();
byte[] dump = out.replace(secret, subFunction.apply(secret)).getBytes();
super.write(dump,0,dump.length);
}
}
right now I have it in a file called MaskingPrintStream.groovy. But, by doing this I effectively can only access this class as an inner class of the class that gets created by default that corresponds to the file name.
What I want to work is code more like this:
def stream = evaluate(new File(ClassLoader.getSystemResource('MaskingPrintStream.groovy').file))
But as you can see, I need to give it some values before it's ready. Perhaps I could load the class into the JVM (not sure how from another groovy script) and then instantiate it the old-fashioned way?
The other problem is: How do I set it up so I don't have this nested class arrangement?
groovy.lang.Script#evaluate(java.lang.String) has a bit different purpose.
For your case you need to use groovy.lang.GroovyClassLoader that is able to parse groovy classes from source, compile and load them. Here's example for your code:
def groovyClassLoader = new GroovyClassLoader(this.class.classLoader) // keep for loading other classes as well
groovyClassLoader.parseClass('MaskingPrintStream.groovy')
def buf = new ByteArrayOutputStream()
def maskingStream = new MaskingPrintStream(new PrintStream(buf), { 'secret' }, { 'XXXXX' })
maskingStream.with {
append 'some text '
append 'secret '
append 'super-duper secret '
append 'other text'
}
maskingStream.close()
println "buf = ${buf}"
And the output it produces in bash shell:
> ./my-script.groovy
buf = some text XXXXX super-duper XXXXX other text
In the section on handling Java Beans with Groovy of Groovy In Action, I found this script (slightly modified):
class Book{
String title
}
def groovyBook = new Book()
// explicit way
groovyBook.setTitle('What the heck, really ?')
println groovyBook.getTitle()
// short-hand way
groovyBook.title = 'I am so confused'
println groovyBook.title
There are no such methods in the class Book so how does that work ?
Yes, they are auto defined and calling book.title is actually calling book.getTitle()
See http://groovy.codehaus.org/Groovy+Beans
You can see this in action with the following script:
def debug( clazz ) {
println '----'
clazz.metaClass.methods.findAll { it.name.endsWith( 'Name' ) || it.name.endsWith( 'Age' ) }.each { println it }
}
class A {
String name
int age
}
debug( A )
// Prints
// public int A.getAge()
// public java.lang.String A.getName()
// public void A.setAge(int)
// public void A.setName(java.lang.String)
// Make name final
class B {
final String name
int age
}
debug( B )
// Prints
// public int B.getAge()
// public java.lang.String B.getName()
// public void B.setAge(int)
// Make name private
class C {
private String name
int age
}
debug( C )
// Prints
// public int C.getAge()
// public void C.setAge(int)
// Try protected
class D {
protected String name
int age
}
debug( D )
// Prints
// public int D.getAge()
// public void D.setAge(int)
// And public?
class E {
public String name
int age
}
debug( E )
// Prints
// public int E.getAge()
// public void E.setAge(int)
Several notes:
For all property fields(public ones only), there are autogenerated accesors.
Default visibility is public. So, you should use private/protected keyword to restrict accessor generation.
Inside an accessor there is direct field access. like this.#title
Inside a constructor you have direct access to! This may be unexpected.
For boolean values there are two getters with is and get prefixes.
Each method with such prefixes, even java ones are treated as accessor, and can be referenced in groovy using short syntax.
But sometimes, if you have ambiguous call there may be class cast exception.
Example code for 4-th point.
class A{
private int i = 0;
A(){
i = 4
println("Constructor has direct access. i = $i")
}
void setI(int val) { i = val; println("i is set to $i"); }
int getI(){i}
}
def a = new A() // Constructor has direct access. i = 4
a.i = 5 // i is set to 5
println a.i // 5
4-th note is important, if you have some logic in accessor, and want it to be applied every time you call it. So in constructor you should explicit call setI() method!
Example for 7
class A{
private int i = 0;
void setI(String val) { println("String version.")}
void setI(int val) { i = val; println("i is set to $i"); }
}
def a = new A()
a.i = 5 // i is set to 5
a.i = "1s5" // GroovyCastException: Cannot cast object '1s5' with class 'java.lang.String' to class 'int'
So, as I see property-like access uses first declared accessor, and don't support overloading. Maybe will be fixed later.
Groovy generates public accessor / mutator methods for fields when and only when there is no access modifier present. For fields declared as public, private or protected no getters and setters will be created.
For fields declared as final only accessors will be created.
All that applies for static fields analogously.
how to alter a substring of a string using replaceAll()
for example using the regular expression "1[a-z]+" (split with "X") and the code:
"this is an example 1one"
should produce:
"this is an example 1Xone"
Try this:
class Test {
public static void main(String[] args) {
String str = "this is an example 1one";
str = str.replaceAll("1([a-z]+)", "1X$1");
System.out.println(str);
}
}
All groovy special character #{\'}${"}/', needs to be replaced by \ in front in a groovy string dynamically
input : anish$spe{cial
output : anish\$spe\{cial
input : anish}stack{overflow'
output : anish\}stack\{overflow\'
I have written a sample program in Java, that i want in groovier way
import java.util.regex.*;
import java.io.*;
/**
*
* #author anish
*
*/
public class EscapeSpecialChar {
public static void main(String[] args) throws IOException {
inputString();
}
private static void inputString() throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter string to find special characters: ");
String string = in.readLine();
// Escape the pattern
string = escapeRE(string);
System.out.println("output: -- " + string);
}
// Returns a pattern where all punctuation characters are escaped.
static Pattern escaper = Pattern.compile("([^a-zA-z0-9])");
public static String escapeRE(String str) {
return escaper.matcher(str).replaceAll("\\\\$1");
}
}
Enter string to find special characters: $Anish(Stack%1231+#$124{}
output: -- \$Anish\(Stack\%1231\+\#\$124\{\}
This does what your Java code does:
System.console().with {
def inStr = readLine 'Enter string to find special characters: '
def outStr = inStr.replaceAll( /([^a-zA-Z0-9])/, '\\\\$1' )
println "Output: $outStr"
}
I am still dubious that what I think you are doing is a good idea though... ;-)