Skip to content

Instantly share code, notes, and snippets.

@michalmela
Last active January 31, 2020 09:05
Show Gist options
  • Save michalmela/0b4db11a4d7ed874d3da63257a9821e2 to your computer and use it in GitHub Desktop.
Save michalmela/0b4db11a4d7ed874d3da63257a9821e2 to your computer and use it in GitHub Desktop.
[jq] #tools
// groovier jq
// example:
// groovy ./jg.groovy "_.collect { it.entrySet().findAll { it.value == null }*.key }.flatten().unique().sort()" ./example.json
// – lists all the properties that are ever null in any of the elements of the root array
@Grab('info.picocli:picocli:2.0.3')
@picocli.groovy.PicocliScript
import groovy.transform.Field
@Grab('info.picocli:picocli:2.0.3')
@picocli.groovy.PicocliScript
@Grab('com.codewaves.codehighlight:codehighlight:1.0.2')
import com.codewaves.codehighlight.core.*
import com.codewaves.codehighlight.languages.*
import com.codewaves.codehighlight.renderer.HtmlRenderer
import groovy.transform.Field
import groovy.json.*
import static picocli.CommandLine.*
@Parameters(index = '0', arity = "1", paramLabel = "SCRIPT", description = """The Groovy transformation to perform on the parsed JSON, referenced as `_`. E.g. `_[0]`, `_*.id`, `_.findAll { it.someNumber > 1 }""")
@Field String script
@Parameters(index = '1', arity = "1", paramLabel = "FILE", description = "The JSON file to analyze.")
@Field File[] files
@Option(names = ["-h", "--help"], usageHelp = true, description = "Show this help message and exit.")
@Field boolean helpRequested
if (helpRequested) {
CommandLine.usage(System.out)
return
}
files.each {
def json = new JsonBuilder(
Eval.me(
'_',
new JsonSlurper().parseText(it.text),
script ?: '_'
)
).toPrettyString()
final Highlighter highlighter = new Highlighter(new RendererFactory())
final Highlighter.HighlightResult result = highlighter.highlight('json', json)
println(result.getResult())
}
class RendererFactory implements StyleRendererFactory {
@Override StyleRenderer create(String languageName) {
new BashRenderer(null)
}
}
public class BashRenderer implements StyleRenderer {
private String mResult;
public BashRenderer(String ignored) {
}
@Override
public void onStart() {
mResult = "";
}
@Override
public void onFinish() {
}
@Override
public void onPushStyle(String style) {
switch(style) {
case 'attr': mResult += "\033[0;31m"
return
case 'number': mResult += "\033[0;32m"
return
case 'string': mResult += "\033[0;33m"
return
case 'literal': mResult += "\033[0;34m"
return
default: mResult += '$$$$$' + style
}
}
@Override
public void onPopStyle() {
mResult += "\033[0m"
}
@Override
public void onPushCodeBlock(CharSequence block) {
mResult += escape(block.toString())
}
@Override
public void onPushSubLanguage(String name, CharSequence code) {
mResult += "<span class=\"" + name + "\">" + code + "</span>";
}
@Override
public void onAbort(CharSequence code) {
mResult = code.toString()
}
@Override
public CharSequence getResult() {
return mResult;
}
private String escape(String code) {
return code.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment