Making shell scripts Groovy
about me
● programmer + DevOps enthusiast
– Java, Groovy, learning Clojure
– Linux, Ansible, Liquibase, Maven
● co-organizing software craftsmanship groups:
– Ruhrgebiet + Düsseldorf (Germany)
– coderetreats, coding dojos
georgberky
georg.berky@valtech-mobility.com
my journey to Groovy
● problem in production
● when contacting a remote system via HTTP
● not enough logging
● but access to the machine
● everything works in curl
my journey to Groovy
● problem has to be inside the JVM
● google: “run Java as a script”
● Groovy!
● some tinkering, some dependencies
● ⇒ missing certificate in Java’s keystore :)
today’s agenda
● shebang + groovyserver
● pipes
● dependency management
● parameter parsing
● external commands
● bonus: XML/JSON
● bonus: FIFOs
● bonus: logging
setup
● install sdkman from sdkman.io
● install groovy using sdkman
– groovy --version should work
● use your favorite editor
● Groovy API
http://docs.groovy-lang.org/latest/html/gapi/
● JDK extensions:
http://groovy-lang.org/gdk.html
getting started
● start with shebang + make executable
● write “hello world” in Java
● use file extension: .groovy
● run: ./HelloWorld.groovy
● leave out as many syntax elements as you can
pipes
● connect two processes
● live outside your root file system
● lifetime: as long as the process creating it
● writing end + reading end
● ends support UNIX file interface
protocol for pipes
● one line is one message
● line buffered
● last producer disconnects: EOF
● preserve order
exercise: using pipes
● write a program that mimics grep
– e.g. grep groovy < input.txt
● read lines from System.in
– hint: use eachLine
● print line if it contains the argument
– hint: use args[0]
testing
● batteries included: JUnit 3 – 5
● power assert
● test doubles: closure + map coercion
● MockFor, StubFor
only in dynamic context
scripts: compiled
exercise: testing
● FizzBuzz Kata
● print all numbers from 1 to 100
● if n divisible by 3, print fizz
● if n divisible by 5, print buzz
● if n divisible by 3 and 5, print fizzbuzz
dependency management
● @Grab(‘org.apache.commons:commons-lang3:3.9’)
● @Grab(group='org.apache.commons',
module='commons-lang3',
version='3.9')
● at runtime: Grape.grab(
group:’org.apache.commons’,
module:’commons-lang3’,
version:’3.9’)
dependency management
● Groovy Grape
● built on top of Apache Ivy
● grabs (transitive) dependencies
– default: from Maven Central
● scripts: replaced with Grape.grab()
– in static initializer
command line options
● Groovy Commons CliBuilder
● @Grab(group='org.codehaus.groovy',
module='groovy-cli-commons',
version='2.5.7')
● import groovy.cli.commons.CliBuilder
● supports short and long options
● now supports typed arguments
exercise: parsing arguments
● use:
@Grab(group='org.codehaus.groovy',
module='groovy-cli-commons',
version='2.5.7')
● extend your grep script:
● ignore case: -i
● invert matching: -v
external commands
● method execute() on String
● e.g. “ls -1”.execute()
● creates and runs instance of Process
● method getText() on Process,
then method eachLine() on String
final assignment
● Producer: prints numbers, one per line
● Consumer: read lines
– increment the number
– print the incremented number
● communicate via pipe
● separate concerns
● test drive as much as you can
suggested design
final assignment - hints
● Isolated tests:
– Map coercion for mocks:
[methodName: { … }] as Interface
– @Grab Mockito for mocks
● integrated tests:
– getInputStream() on Process
– getOutputStream() on Process
●
got interested?
● Previous work: Sascha Klein - “Groovy on the Shell”
– https://tinyurl.com/groovy-on-the-shell
● Georg Berky - “Groovy Shell Scripting”
(Never Code Alone Blog)
– http://tinyurl.com/groovy-shell-1
– http://tinyurl.com/groovy-shell-2
– http://tinyurl.com/groovy-shell-3
Videoplasty.com [CC BY-SA 4.0 (https://creativecommons.org/licenses/by-sa/4.0)]
thank you!
georgberky
georg.berky@valtech-mobility.com

Groovy shell scripting

  • 1.
  • 2.
    about me ● programmer+ DevOps enthusiast – Java, Groovy, learning Clojure – Linux, Ansible, Liquibase, Maven ● co-organizing software craftsmanship groups: – Ruhrgebiet + Düsseldorf (Germany) – coderetreats, coding dojos georgberky [email protected]
  • 3.
    my journey toGroovy ● problem in production ● when contacting a remote system via HTTP ● not enough logging ● but access to the machine ● everything works in curl
  • 4.
    my journey toGroovy ● problem has to be inside the JVM ● google: “run Java as a script” ● Groovy! ● some tinkering, some dependencies ● ⇒ missing certificate in Java’s keystore :)
  • 5.
    today’s agenda ● shebang+ groovyserver ● pipes ● dependency management ● parameter parsing ● external commands ● bonus: XML/JSON ● bonus: FIFOs ● bonus: logging
  • 6.
    setup ● install sdkmanfrom sdkman.io ● install groovy using sdkman – groovy --version should work ● use your favorite editor ● Groovy API http://docs.groovy-lang.org/latest/html/gapi/ ● JDK extensions: http://groovy-lang.org/gdk.html
  • 7.
    getting started ● startwith shebang + make executable ● write “hello world” in Java ● use file extension: .groovy ● run: ./HelloWorld.groovy ● leave out as many syntax elements as you can
  • 8.
    pipes ● connect twoprocesses ● live outside your root file system ● lifetime: as long as the process creating it ● writing end + reading end ● ends support UNIX file interface
  • 9.
    protocol for pipes ●one line is one message ● line buffered ● last producer disconnects: EOF ● preserve order
  • 10.
    exercise: using pipes ●write a program that mimics grep – e.g. grep groovy < input.txt ● read lines from System.in – hint: use eachLine ● print line if it contains the argument – hint: use args[0]
  • 11.
    testing ● batteries included:JUnit 3 – 5 ● power assert ● test doubles: closure + map coercion ● MockFor, StubFor only in dynamic context scripts: compiled
  • 12.
    exercise: testing ● FizzBuzzKata ● print all numbers from 1 to 100 ● if n divisible by 3, print fizz ● if n divisible by 5, print buzz ● if n divisible by 3 and 5, print fizzbuzz
  • 13.
    dependency management ● @Grab(‘org.apache.commons:commons-lang3:3.9’) ●@Grab(group='org.apache.commons', module='commons-lang3', version='3.9') ● at runtime: Grape.grab( group:’org.apache.commons’, module:’commons-lang3’, version:’3.9’)
  • 14.
    dependency management ● GroovyGrape ● built on top of Apache Ivy ● grabs (transitive) dependencies – default: from Maven Central ● scripts: replaced with Grape.grab() – in static initializer
  • 15.
    command line options ●Groovy Commons CliBuilder ● @Grab(group='org.codehaus.groovy', module='groovy-cli-commons', version='2.5.7') ● import groovy.cli.commons.CliBuilder ● supports short and long options ● now supports typed arguments
  • 16.
    exercise: parsing arguments ●use: @Grab(group='org.codehaus.groovy', module='groovy-cli-commons', version='2.5.7') ● extend your grep script: ● ignore case: -i ● invert matching: -v
  • 17.
    external commands ● methodexecute() on String ● e.g. “ls -1”.execute() ● creates and runs instance of Process ● method getText() on Process, then method eachLine() on String
  • 18.
    final assignment ● Producer:prints numbers, one per line ● Consumer: read lines – increment the number – print the incremented number ● communicate via pipe ● separate concerns ● test drive as much as you can
  • 19.
  • 20.
    final assignment -hints ● Isolated tests: – Map coercion for mocks: [methodName: { … }] as Interface – @Grab Mockito for mocks ● integrated tests: – getInputStream() on Process – getOutputStream() on Process ●
  • 21.
    got interested? ● Previouswork: Sascha Klein - “Groovy on the Shell” – https://tinyurl.com/groovy-on-the-shell ● Georg Berky - “Groovy Shell Scripting” (Never Code Alone Blog) – http://tinyurl.com/groovy-shell-1 – http://tinyurl.com/groovy-shell-2 – http://tinyurl.com/groovy-shell-3 Videoplasty.com [CC BY-SA 4.0 (https://creativecommons.org/licenses/by-sa/4.0)]
  • 22.