Skip to content

Jbang script demo

Posted on:January 16, 2023 at 01:00 PM

In this demo, I will draft a cli tool with two actions:

This is a basic two-steps scenario which can be extended into a chain of actions to accomplish a specific tasks.

In this task, we will see:

Installation:

curl -Ls https://sh.jbang.dev | bash -s - app setup

IntelliJ plugin installation:

Jbang IDE plugin Figure: Jbang plugin - version 0.23.0

Demo script (GitHub repo)

Script objectives:

Dependency management

Jbang will handle those maven dependencies for us.

//DEPS info.picocli:picocli:4.6.3
//DEPS com.konghq:unirest-java:3.14.1
//DEPS com.konghq:unirest-object-mappers-gson:3.14.1

Share class files to compiler

Jbang will include java class files under directory model. In this directory, I have a POJO class file defining response model from API

//SOURCES models

Here is the Quote.java

package models;

public class Quote {
    String quote;
    String author;

    public String getQuote() {
        return quote;
    }

    public void setQuote(String quote) {
        this.quote = quote;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }
}

Full script:

///usr/bin/env jbang "$0" "$@" ; exit $?

//DEPS info.picocli:picocli:4.6.3
//DEPS com.konghq:unirest-java:3.14.1
//DEPS com.konghq:unirest-object-mappers-gson:3.14.1
//SOURCES models

import kong.unirest.GenericType;
import kong.unirest.Unirest;
import models.Quote;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Parameters;

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.stream.Collectors;

@Command(name = "bbquote", mixinStandardHelpOptions = true, version = "BreakingBadCli 0.1",
        description = "BreakingBadCli made with jbang")
class bbquote implements Callable<Integer> {

    @Parameters(index = "0", description = "input file with characters")
    private Path path;

    public static void main(String... args) {
        int exitCode = new CommandLine(new bbquote()).execute(args);
        System.exit(exitCode);
    }

    @Override
    public Integer call() throws Exception {
        var characters = Files.readAllLines(path);
        characters.forEach(character -> {
            var res = Unirest.get("https://api.breakingbadquotes.xyz/v1/quotes/50")
                    .asObject(new GenericType<List<Quote>>() {
                    })
                    .getBody();
            var filteredQuote = res.stream()
                    .filter(item -> item.getAuthor().contains(character))
                    .collect(Collectors.toList());
            if (filteredQuote.size() > 0) {
                System.out.println(character + " once says...");
                filteredQuote.forEach(quote -> System.out.println("..." + quote.getQuote()));
            }
        });
        return 0;
    }
}

Jbang usage:

Open a terminal at src/main/java then issue those commands to build and use the cli:

cd src/main/java
jbang app install bbquote.java
bbquote characters.txt

Sample output:

Jess once says...
...Hey, tell your douchebag brother-in-law to head towards the light
...You add plus a douchebag to a minus douchebag and you get, Like, Zero Douchebags.
...Fire in the hole, bitch!
...Yeah, bitch! Magnets!
...You don’t want a criminal lawyer. You want a criminal lawyer.
...Seriously? "Hello Kitty"?
...Did you just bring a bomb into a hospital?
...So roll me further bitch!
...You're my free pass... bitch!
Hank once says...
...I will put you under the jail.