Skip to content

philippart-s/jarvis

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Discover Picocli

Here you can find the different steps to create your first CLI in Java with the Picocli Framework. The main steps of the project are stored each in a separate git branch chronological named with numbers.

🎉 - 01-Init project

  • all the resulted source code will be find in the branch 01-🎉-Init-Project
  • init the Quarkus project: quarkus create cli fr.wilda.picocli:jarvis:0.0.1-SNAPSHOT --no-wrapper
$ quarkus create cli fr.wilda.picocli:jarvis:0.0.1-SNAPSHOT  
Looking for the newly published extensions in registry.quarkus.io
-----------
selected extensions: 
- io.quarkus:quarkus-picocli


applying codestarts...
📚 java
🔨 maven
📦 quarkus
📝 config-properties
🔧 dockerfiles
🔧 maven-wrapper
🚀 picocli-codestart

-----------
[SUCCESS] ✅  quarkus project has been successfully generated in:
--> /Users/stef/xxx/jarvis
-----------
Navigate into this directory and get started: quarkus dev
  • let's see what the command generated:
    • a pom.xml with all necessary dependences
      • take look to the dependecies section with a reference to the picocli extension
    • an example class, GreetingCommand
      • take a look to the annotations :
        • @Command(name = "greeting", mixinStandardHelpOptions = true): 'mixinStandardHelpOptions' adds the --help and --version options
        • @Parameters(paramLabel = "<name>", defaultValue = "picocli", description = "Your name."): parameter to set to the CLI, if empty use the defaultValue value. The description parameter will be displayed when calling the --help option
    • a set of Dockerfiles in src/main/docker
    • an empty application.properties

02-Try the CLI

  • all the resulted source code will be find in the branch 02-📺-Try-the-CLI
  • first use the Quarkus dev mode: quarkus dev:
$ quarkus dev

__  ____  __  _____   ___  __ ____  ______ 
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \   
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/   
2023-10-29 18:46:11,317 INFO  [io.quarkus] (Quarkus Main Thread) jarvis 0.0.1-SNAPSHOT on JVM (powered by Quarkus 3.5.0) started in 0.497s. 

2023-10-29 18:46:11,319 INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2023-10-29 18:46:11,319 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, picocli]
Hello picocli, go go commando!

2023-10-29 18:46:11,354 INFO  [io.quarkus] (Quarkus Main Thread) jarvis stopped in 0.002s

--
Tests paused
Press [space] to restart, [e] to edit command line args (currently ''), [r] to resume testing, [o] Toggle test output, [:] for the terminal, [h] for more options>
  • press e to test the CLI as you were in a terminal:
2023-10-29 18:46:11,354 INFO  [io.quarkus] (Quarkus Main Thread) jarvis stopped in 0.002s

--
Tests paused
-h

Usage: greeting [-hV] <name>
      <name>      Your name.
  -h, --help      Show this help message and exit.
  -V, --version   Print version information and exit.

2023-07-29 14:54:51,389 INFO  [io.quarkus] (Quarkus Main Thread) discover-picocli stopped in 0.000s

--
Tests paused
Press [space] to restart, [e] to edit command line args (currently ''), [r] to resume testing, [o] Toggle test output, [:] for the terminal, [h] for more options>

--
Tests paused
Stéphane

2023-07-29 14:58:33,334 INFO  [io.qua.dep.dev.RuntimeUpdatesProcessor] (Aesh InputStream Reader) Live reload total time: 0.097s 
Hello Stéphane, go go commando!

2023-10-29 18:51:31,003 INFO  [io.quarkus] (Quarkus Main Thread) jarvis stopped in 0.000s
--
Tests paused
Press [space] to restart, [e] to edit command line args (currently ''), [r] to resume testing, [o] Toggle test output, [:] for the terminal, [h] for more options>

03-ovhcloud-sdk

  • all the resulted source code will be find in the branch 03-🔗-ovhcloud-sdk
  • add the rest client reactive client: quarkus extension add rest-client-reactive-jackson (see it in the dependencies section in the pom.xml)
  • add the jarvis-sdk dependency in the pom.xml:
    <dependency>
      <groupId>fr.wilda.jarvis.sdk</groupId>
      <artifactId>jarvis-sdk</artifactId>
      <version>1.0.0</version>
    </dependency>
  • create the API Service that is responsible to call the OVHcloud API: OVHcloudAPIService.java
  • take a look to the Jakarta annotations:
    • @RegisterRestClient: to use it as client to do API call, see application.properties for parameters
    • @Path("/v1"): root path for the called end-point
    • @ClientHeaderParam(name = "X-Ovh-Consumer", value = "${ovhcloud.consumer}"), @ClientHeaderParam(name = "X-Ovh-Application", value = "${ovhcloud.application}"), @ClientHeaderParam(name = "Content-Type", value = "application/json"): header parameters, see application.properties for dynamic parameters
  • add the following dependency in the pom.xml:
<dependency>
  <groupId>io.quarkiverse.langchain4j</groupId>
  <artifactId>quarkus-langchain4j-mistral-ai</artifactId>
  <version>0.10.3</version>
</dependency>
quarkus.langchain4j.mistralai.api-key=foo
quarkus.langchain4j.mistralai.chat-model.max-tokens=150
quarkus.langchain4j.mistralai.chat-model.model-name=Mistral-7B-Instruct-v0.2

quarkus.langchain4j.mistralai.log-requests=true
quarkus.langchain4j.mistralai.log-responses=true

⚠️ you need to set the environment variable QUARKUS_LANGCHAIN4J_MISTRALAI_BASE_URL with the API URL of Mistral model. ⚠️

04-🤖-create-jarvis

  • all the resulted source code will be find in the branch 04-🤖-add-ovhcloud-feature
  • create the main entry point for the CLI: JarvisCommand.java
  • delete the GreetingCommand.java file
  • test your CLI with the developer mode: quarkus dev

05-☁️-add-ovhcloud-command

  • all the resulted source code will be find in the branch 05-☁️-add-ovhcloud-command
  • create the OVHcloud sub command to access to the REST API: OVHcloudSubCommand.java
    • take a look to the annotations:
      • @Option(names = {"-m", "--me"}, description = "Display the OVHcloud account details."), @Option(names = {"-k", "--kube"}, description = "Display your Managed Kubernetes Service created."): create boolean options activated when setted
      • @RestClient: to use the API Service class OVHcloudAPIService
      • @ConfigProperty(name = "ovhcloud.projectId"): to get the value of the key ovhcloud.projectId from application.properties file.
  • update the JarvisCommand.java with the @TopCommand annotation and the sub command list subcommands = {OVHcloudSubCommand.class}
  • test the new subcommand: ovhcloud -m -k
  • to use AI Endpoints:
@Inject
  AIEndpointMistral7bService aiEndpointMistral7bService;
  • update the parameter name to become the question to ask:
 // Question to ask
  @Parameters(paramLabel = "<question>", defaultValue = "Can you explain what are you?", description = "The question to ask to Jarvis.")
  private String question;
  • update the call method:
@Override
  public Integer call() throws Exception {
    _LOG.info("{}", aiEndpointMistral7bService.askAQuestion(question));

    return 0;
  }

06-📦-package

  • all the resulted source code will be find in the branch 06-📦-package
  • update the application.properties to have clean outputs: %prod.quarkus.log.category."fr.wilda".level=INFO & %prod.quarkus.log.console.format=%m
  • launch the build Quarkus command: quarkus build
    • take a look that the application is available in target/quarkus-app folder, espacially the lib folder
    • take a look to the generated application: du -h --max-depth=1
  • test the packaged CLI: java -jar ./target/quarkus-app/quarkus-run.jar Stéphane, java -jar ./target/quarkus-app/quarkus-run.jar ovhcloud -m -k
  • create the jarvis.sh script
  • in the src/main/script folder, test the CLI: ./jarvis.sh ovhcloud -m -k

07-🚀-graalvm

  • all the resulted source code will be find in the branch 07-🚀-graalvm
  • if needed install GraalVM: https://www.graalvm.org/latest/docs/getting-started/
  • set the GRAALVM_HOME environment variable: export GRAALVM_HOME=/Library/Java/JavaVirtualMachines/graalvm-jdk-17.0.8+9.1/Contents/Home
  • ⚠️ if your /tmp is mounted as noexec: change the java.io.tmpdir to a folder with exec permission by adding the following property on your build command: -Dquarkus.native.additional-build-args=-Djava.io.tmpdir=$HOME/tmp or use the experimental building feature: quarkus build --native -Dquarkus.native.container-build=true ⚠️
  • build the binary with the command quarkus build --native
  • use the generated CLI: ./target/jarvis-0.0.1-SNAPSHOT-runner ovhcloud -m -k or use the backuped one: jarvis_bck ovhcloud -m -k
  • rename and move the generated CLI: cp ./target/jarvis-0.0.1-SNAPSHOT-runner ~/bin/jarvis && mv ~/bin/jarvis-0.0.1-SNAPSHOT-runner jarvis
  • use the CLI: jarvis ovhcloud -m

About

Code source to discover how to code a CLI with Picocli and Quarkus

Resources

License

Stars

Watchers

Forks

Packages

No packages published