Skip to content

Instantly share code, notes, and snippets.

@geowarin
Last active August 29, 2015 14:10
Show Gist options
  • Save geowarin/4eaadeb9589a85ed6500 to your computer and use it in GitHub Desktop.
Save geowarin/4eaadeb9589a85ed6500 to your computer and use it in GitHub Desktop.
Power Template® by geowarin. Use the power of groovy to templatize a file.
#!/usr/bin/env groovy
import groovy.json.JsonSlurper
import groovy.text.SimpleTemplateEngine
import org.apache.commons.cli.HelpFormatter
def template = new PowerTemplate()
template.parseOptions(args)
template.run()
class PowerTemplate {
def cli
def template = System.in.newReader()
def output
File[] bindingFiles
void run() {
def binding = getBindings();
binding += [
env: System.getenv(),
cmd: { s ->
def proc = s.execute()
proc.waitFor()
return proc.in.text
}
]
def template = new SimpleTemplateEngine().createTemplate(template.text).make(binding)
output.class == File && output.exists() && output.delete()
output << template.toString()
}
Map getBindings() {
bindingFiles
.collect { it.exists() ? new JsonSlurper().parse(it) : [:] }
.inject([:]) { acc, value -> acc + value }
}
void parseOptions(args) {
cli = new CliBuilder(
formatter: new MyHelp(),
header: 'Power Template® by geowarin.',
usage: 'template (-f file) (-o outputFile) (-v values1.json values2.json)',
footer: '''
Use the power of groovy to templatize a file.
If file no file parameter present, the template will be read from standard input.
It can contain values within ${}. You can use any groovy expressions.
You can use json files to put values into the template.
Use ${env['someProperty']} to access environment variables.
Use ${cmd('command')} to include the output of a command.
''')
cli.help('print this message')
cli.f(args: 1, argName: 'file', 'The file to templatize')
cli.o(args: 1, argName: 'output', 'Optional. Redirect the result to a file')
cli.v(args: -2, argName: 'vars', 'Optional. Point to one or several json files to put values into the template')
OptionAccessor options = cli.parse(args)
options.help && exitWithMessage()
if (options.f) {
template = new File(options.f)
template.exists() || exitWithMessage("File not found ${template}")
}
output = options.o ? new File(options.o) : System.out
bindingFiles = options.vs ? options.vs.collect { new File(it) } : []
}
void exitWithMessage(String message = null) {
message && System.err.println(message)
cli.usage()
System.exit(1)
}
}
// Hack to preserve line endings in usage. Don't care about max width
class MyHelp extends HelpFormatter {
protected int findWrapPos(String text, int width, int startPos) {
return text.lastIndexOf('\n', startPos)
}
}
@geowarin
Copy link
Author

usage: template -f file (-o outputFile) (-v values1.json values2.json)
Power Template® by geowarin.
-f The file to templatize
-o Optional. Redirect the result to a file
-v Optional. Point to one or several json files to put values into the template

Use the power of groovy to templatize a file.
It can contain values within ${}.
You can use any groovy expressions.

You can use json files to put values into the template.
Use ${env['someProperty']} to access environment variables.
Use ${cmd('command')} to include the output of a command.

Example of template :
RUBY=${ env['PATH'].split(':').findAll { it =~ '(?i)ruby'} }
SYSTEM=${ cmd('uname') }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment