Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,20 @@ dependencies {
implementation("info.picocli:picocli")
implementation("info.picocli:picocli-jansi-graalvm:1.2.0")
implementation("org.fusesource.jansi:jansi:2.4.2")
implementation("info.picocli:picocli-shell-jline3:4.7.6")
implementation("org.jline:jline:3.30.5")
implementation("io.micronaut:micronaut-http-client")
implementation("io.micronaut.picocli:micronaut-picocli")
implementation("io.micronaut.serde:micronaut-serde-jackson")
testImplementation("net.datafaker:datafaker:2.5.1")
compileOnly("org.projectlombok:lombok")
runtimeOnly("ch.qos.logback:logback-classic")
runtimeOnly("org.yaml:snakeyaml")
}


application {
mainClass = "org.justserve.BaseCommand"
mainClass = "org.justserve.cli.JustServeCommand"
}

java {
Expand Down Expand Up @@ -76,6 +79,7 @@ micronaut {
graalvmNative.binaries {
named("main") {
imageName.set("justserve")
buildArgs.add("--color=always")
}
}

Expand Down
26 changes: 26 additions & 0 deletions compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
services:
linux-shell:
image: ghcr.io/graalvm/native-image-community:21-muslib
container_name: justserve-linux-shell
working_dir: /app
volumes:
- .:/app
env_file: .env
entrypoint: /bin/sh
command:
- -c
- "mkdir -p /temp_app && cp -r . /temp_app/ && cd /temp_app && microdnf install -y findutils && sed -i 's/\r$//' ./gradlew && if [ -t 0 ]; then /bin/bash; else tail -f /dev/null; fi"
stdin_open: true
tty: true

linux-test:
image: ghcr.io/graalvm/native-image-community:21-muslib
container_name: justserve-linux-test
working_dir: /app
volumes:
- .:/app
env_file: .env
entrypoint: /bin/sh
command:
- -c
- "mkdir -p /temp_app && cp -r . /temp_app/ && cd /temp_app && microdnf install -y findutils && sed -i 's/\r$//' ./gradlew && ./gradlew test"
3 changes: 2 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
micronautVersion=4.8.3
justserveCliVersion=0.0.4
justserveCliVersion=0.0.5-SNAPSHOT
org.gradle.console=rich
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.justserve;
package org.justserve.auth;

import io.micronaut.context.annotation.Property;
import io.micronaut.context.annotation.Requires;
Expand Down
28 changes: 28 additions & 0 deletions src/main/java/org/justserve/cli/JustServeCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.justserve.cli;

import io.micronaut.configuration.picocli.PicocliRunner;
import org.justserve.cli.command.BaseCommand;
import org.justserve.cli.command.GetTempPassword;
import org.justserve.cli.util.JustServeVersionProvider;
import picocli.CommandLine.Command;
import picocli.CommandLine.ParameterException;
import picocli.jansi.graalvm.AnsiConsole;

@Command(subcommands = GetTempPassword.class,
mixinStandardHelpOptions = true,
name = "justserve", versionProvider = JustServeVersionProvider.class,
description = "justserve-cli is a terminal tool to help specialists and admin using JustServe")
public class JustServeCommand extends BaseCommand implements Runnable {

public static void main(String[] args) {
try (AnsiConsole ignored = AnsiConsole.windowsInstall()) {
PicocliRunner.run(JustServeCommand.class, args);
}

}

@Override
public void run() {
throw new ParameterException(spec.commandLine(), "No command specified");
}
}
70 changes: 70 additions & 0 deletions src/main/java/org/justserve/cli/command/BaseCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package org.justserve.cli.command;

import io.micronaut.core.annotation.NonNull;
import io.micronaut.core.annotation.ReflectiveAccess;
import picocli.CommandLine.Command;
import picocli.CommandLine.Model.CommandSpec;
import picocli.CommandLine.Spec;

import java.io.PrintWriter;
import java.util.Optional;

import static picocli.CommandLine.Help.Ansi.AUTO;

@Command
public class BaseCommand implements ConsoleOutput{

@Spec
@ReflectiveAccess
protected CommandSpec spec;


@Override
public void out(String message) {
outWriter().ifPresent(writer -> writer.println(AUTO.string(message)));
}

public void err(String message) {
errWriter().ifPresent(writer -> writer.println(AUTO.string("@|bold,red | Error|@ " + message)));
}

public void warning(String message) {
outWriter().ifPresent(writer -> writer.println(AUTO.string("@|bold,red | Warning|@ " + message)));
}

@Override
public void green(String message) {
outWriter().ifPresent(writer -> writer.println(AUTO.string("@|bold,green " + message + "|@")));
}

@Override
public void red(String message) {
outWriter().ifPresent(writer -> writer.println(AUTO.string("@|bold,red " + message + "|@")));
}

@Override
public boolean showStacktrace() {
return false;
}

@Override
public boolean verbose() {
return false;
}


@NonNull
public Optional<PrintWriter> outWriter() {
return getSpec().map(spec -> spec.commandLine().getOut());
}

@NonNull
public Optional<PrintWriter> errWriter() {
return getSpec().map(spec -> spec.commandLine().getErr());
}

@NonNull
public Optional<CommandSpec> getSpec() {
return Optional.ofNullable(spec);
}
}
34 changes: 34 additions & 0 deletions src/main/java/org/justserve/cli/command/CommonOptionsMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.justserve.cli.command;

import io.micronaut.core.annotation.ReflectiveAccess;
import org.justserve.cli.util.JustServeVersionProvider;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;

/**
* Mixin that adds help, version and other common options to a command. Example usage:
* <pre>
* &#064;Command(name = "command")
* class App {
* &#064;Mixin
* CommonOptionsMixin commonOptions // adds common options to the command
*
* // ...
* }
* </pre>
*
* @author Jonathan Zollinger
* @version 0.0.1
*/
@Command(mixinStandardHelpOptions = true, versionProvider = JustServeVersionProvider.class)
@SuppressWarnings("checkstyle:VisibilityModifier")
public class CommonOptionsMixin {

@Option(names = {"-x", "--stacktrace"}, defaultValue = "false", description = "Show full stack trace when exceptions occur.")
@ReflectiveAccess
public boolean showStacktrace;

@Option(names = {"-v", "--verbose"}, defaultValue = "false", description = "Create verbose output.")
@ReflectiveAccess
public boolean verbose;
}
43 changes: 43 additions & 0 deletions src/main/java/org/justserve/cli/command/ConsoleOutput.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.justserve.cli.command;

public interface ConsoleOutput {
ConsoleOutput NOOP = new ConsoleOutput() {
@Override
public void out(String message) { }

@Override
public void err(String message) { }

@Override
public void warning(String message) { }

@Override
public boolean showStacktrace() {
return false;
}

@Override
public boolean verbose() {
return false;
}

};

void out(String message);

void err(String message);

void warning(String message);

boolean showStacktrace();

boolean verbose();

default void green(String message) {
out(message);
}

default void red(String message) {
out(message);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.justserve;
package org.justserve.cli.command;

import io.micronaut.configuration.picocli.PicocliRunner;
import io.micronaut.context.annotation.Value;
import io.micronaut.core.annotation.ReflectiveAccess;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.client.exceptions.HttpClientResponseException;
import jakarta.inject.Inject;
Expand All @@ -10,44 +10,28 @@
import org.justserve.model.UserHashRequestByEmail;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.jansi.graalvm.AnsiConsole;

import static org.justserve.JustServePrinter.printError;
import static org.justserve.JustServePrinter.printNormal;
import static org.justserve.cli.util.JustServePrinter.printError;
import static org.justserve.cli.util.JustServePrinter.printNormal;

@Command(name = "justserve",
description = "justserve-cli is a terminal tool to help specialists and admin using JustServe")
public class BaseCommand implements Runnable {
@Command(name = "getTempPassword", description = "get a temporary password for a user")
public class GetTempPassword extends BaseCommand implements Runnable {

@ReflectiveAccess
@Option(names = {"-e", "--email"}, description = "email for the user whose temporary password will be generated")
String email;

@Option(names = {"version", "--version", "-v"})
boolean version = false;

@Value("${micronaut.application.version}")
String justserveCliVersion;

@Inject
@ReflectiveAccess
Provider<UserClient> userClientProvider;

@Value("${justserve.token}")
String token;

public static void main(String[] args) {
try (AnsiConsole ignored = AnsiConsole.windowsInstall()) {
PicocliRunner.run(BaseCommand.class, args);
}

}

@Override
public void run() {
if (version) {
printNormal(justserveCliVersion);
return;
}
HttpResponse<String> response;
if ("i-need-to-be-defined".equals(token) || null == token ) {
if ("i-need-to-be-defined".equals(token) || null == token) {
printError(("NO AUTHENTICATION PROVIDED" + System.lineSeparator() +
"The Authentication token is not assigned as an environment variable." + System.lineSeparator() +
"Please define the environment variable \"JUSTSERVE_TOKEN\" and try again."));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.justserve;
package org.justserve.cli.util;

import org.fusesource.jansi.Ansi;

Expand All @@ -13,13 +13,13 @@
public final class JustServePrinter {

private final static Ansi blue = ansi().fgRgb(0, 158, 185);
private final static Ansi orange = ansi().fgRgb(239, 94, 57);
private final static Ansi orange = ansi().fgRgb(255, 140, 0); // OG color is 239, 94, 57
private final static Ansi red = ansi().fgRgb(233, 59, 84); // I definitely eyeballed this one
private final static Ansi yellow = ansi().fgRgb(225, 188, 33);

private final static Ansi normalStyle = ansi().reset();
private final static Ansi titleStyle = blue;
private final static Ansi emphasisStyle = orange;
private final static Ansi titleStyle = blue.bold();
private final static Ansi emphasisStyle = orange.bold();
private final static Ansi warningStyle = yellow;
private final static Ansi errorTitleStyle = red.bold();
private final static Ansi errorInfoStyle = ansi().reset();
Expand All @@ -32,14 +32,18 @@ private JustServePrinter() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}

private static void jsPrint(String message, Ansi... style) {
private static String applyStyle(String message, Ansi... style) {
Ansi styledMessage = stream(style).reduce(ansi(), Ansi::a, Ansi::a);
System.out.println(styledMessage.a(message).reset());
return styledMessage.a(message).reset().toString();
}

private static void jsPrint(String message, Ansi... style) {
System.out.println(applyStyle(message, style));
}


private static void jsPrintErr(String message, Ansi... style) {
Ansi styledMessage = stream(style).reduce(ansi(), Ansi::a, Ansi::a);
System.err.println(styledMessage.a(message).reset());
System.err.println(applyStyle(message, style));
}

/**
Expand All @@ -51,6 +55,24 @@ public static void printNormal(String message) {
jsPrint(message, normalStyle);
}

/**
* Returns a String stylized in Orange.
*
* @param message The message to print.
*/
public static String styleTitle(String message) {
return applyStyle(message, titleStyle);
}

/**
* Returns a String stylized in the designated emphasis style.
*
* @param message The message to print.
*/
public static String styleEmphasis(String message) {
return applyStyle(message, emphasisStyle);
}

/**
* Prints an error message to the standard error stream in red.
*
Expand Down
Loading