diff --git a/app/src/main/java/zeroecho/CovertCommand.java b/app/src/main/java/zeroecho/CovertCommand.java index 2e584a8..c628e0e 100644 --- a/app/src/main/java/zeroecho/CovertCommand.java +++ b/app/src/main/java/zeroecho/CovertCommand.java @@ -132,17 +132,17 @@ public final class CovertCommand { * @throws ParseException if the arguments are invalid or incomplete */ public static int main(String[] args, Options options) throws ParseException { - final Option EMBED_OPTION = Option.builder().longOpt("embed").desc("Embed a payload into a JPEG").build(); - final Option EXTRACT_OPTION = Option.builder().longOpt("extract").desc("Extract a payload from a JPEG").build(); + final Option EMBED_OPTION = Option.builder().longOpt("embed").desc("Embed a payload into a JPEG").get(); + final Option EXTRACT_OPTION = Option.builder().longOpt("extract").desc("Extract a payload from a JPEG").get(); final Option JPEG_OPTION = Option.builder().longOpt("jpeg").hasArg().argName("input.jpg") - .desc("Input JPEG file").required().build(); + .desc("Input JPEG file").required().get(); final Option PAYLOAD_OPTION = Option.builder().longOpt("payload").hasArg().argName("payload.dat") - .desc("Binary payload file to embed").build(); + .desc("Binary payload file to embed").get(); final Option OUTPUT_OPTION = Option.builder().longOpt("output").hasArg().argName("outputFile") - .desc("Output JPEG or payload file").required().build(); + .desc("Output JPEG or payload file").required().get(); final Option SLOTS_OPTION = Option.builder().longOpt("slots").hasArgs().valueSeparator(';') .argName("slot1;slot2;...") - .desc("Custom EXIF slots (e.g. Exif.UserComment:4096;Exif.Custom/tag=700,ascii,64,exif:1024)").build(); + .desc("Custom EXIF slots (e.g. Exif.UserComment:4096;Exif.Custom/tag=700,ascii,64,exif:1024)").get(); OptionGroup modeGroup = new OptionGroup(); modeGroup.addOption(EMBED_OPTION); diff --git a/app/src/main/java/zeroecho/Guard.java b/app/src/main/java/zeroecho/Guard.java index ad7751a..0f0129e 100644 --- a/app/src/main/java/zeroecho/Guard.java +++ b/app/src/main/java/zeroecho/Guard.java @@ -128,71 +128,71 @@ public final class Guard { // ---- operation selection final Option OPT_ENCRYPT = Option.builder("e").longOpt("encrypt").hasArg().argName("in-file") - .desc("Encrypt the given file").build(); + .desc("Encrypt the given file").get(); final Option OPT_DECRYPT = Option.builder("d").longOpt("decrypt").hasArg().argName("in-file") - .desc("Decrypt the given file").build(); + .desc("Decrypt the given file").get(); final OptionGroup OP = new OptionGroup().addOption(OPT_ENCRYPT).addOption(OPT_DECRYPT); OP.setRequired(true); // ---- common I/O final Option OPT_OUT = Option.builder("o").longOpt("output").hasArg().argName("out-file") - .desc("Output file (default: .enc for encrypt, .dec for decrypt)").build(); + .desc("Output file (default: .enc for encrypt, .dec for decrypt)").get(); final Option OPT_KEYRING = Option.builder().longOpt("keyring").hasArg().argName("keyring.txt") - .desc("KeyringStore file for aliases (required when aliases are used)").build(); + .desc("KeyringStore file for aliases (required when aliases are used)").get(); // ---- payload selection and parameters final Option OPT_ALG = Option.builder().longOpt("alg").hasArg().argName("name") .desc("Payload: aes-gcm | aes-ctr | aes-cbc-pkcs7 | aes-cbc-nopad | chacha-aead | chacha-stream " + "(default: aes-gcm)") - .build(); + .get(); final Option OPT_AAD_HEX = Option.builder("a").longOpt("aad-hex").hasArg().argName("hex") - .desc("Additional authenticated data as hex (AEAD modes)").build(); + .desc("Additional authenticated data as hex (AEAD modes)").get(); final Option OPT_TAG_BITS = Option.builder().longOpt("tag-bits").hasArg().argName("96..128") - .desc("AES-GCM tag length in bits (default 128)").build(); + .desc("AES-GCM tag length in bits (default 128)").get(); final Option OPT_NONCE_HEX = Option.builder().longOpt("nonce-hex").hasArg().argName("hex") - .desc("ChaCha nonce (12-byte hex)").build(); + .desc("ChaCha nonce (12-byte hex)").get(); final Option OPT_INIT_CTR = Option.builder().longOpt("init-ctr").hasArg().argName("int") - .desc("ChaCha stream initial counter (default 1)").build(); + .desc("ChaCha stream initial counter (default 1)").get(); final Option OPT_CTR = Option.builder().longOpt("ctr").hasArg().argName("int") - .desc("ChaCha stream counter override (propagated via context)").build(); + .desc("ChaCha stream counter override (propagated via context)").get(); final Option OPT_NO_HDR = Option.builder().longOpt("no-header") - .desc("Do not write or expect a symmetric header").build(); + .desc("Do not write or expect a symmetric header").get(); // ---- envelope parameters final Option OPT_CEK_BYTES = Option.builder().longOpt("cek-bytes").hasArg().argName("len") - .desc("Payload key (CEK) length in bytes (default 32)").build(); + .desc("Payload key (CEK) length in bytes (default 32)").get(); final Option OPT_MAX_RECIPS = Option.builder().longOpt("max-recipients").hasArg().argName("n") - .desc("Max recipients in the envelope header (default 64)").build(); + .desc("Max recipients in the envelope header (default 64)").get(); final Option OPT_MAX_ENTRY = Option.builder().longOpt("max-entry-len").hasArg().argName("bytes") - .desc("Max single recipient-entry length (default 1048576)").build(); + .desc("Max single recipient-entry length (default 1048576)").get(); final Option OPT_NO_SHUFFLE = Option.builder().longOpt("no-shuffle") - .desc("Disable shuffling of recipients (enabled by default)").build(); + .desc("Disable shuffling of recipients (enabled by default)").get(); // ---- recipients (real) final Option OPT_TO_ALIAS = Option.builder().longOpt("to-alias").hasArg().argName("alias") - .desc("Add recipient by alias from keyring (repeatable)").build(); + .desc("Add recipient by alias from keyring (repeatable)").get(); final Option OPT_TO_PSW = Option.builder().longOpt("to-psw").hasArg().argName("password") - .desc("Add password recipient (repeatable)").build(); + .desc("Add password recipient (repeatable)").get(); final Option OPT_PSW_ITER = Option.builder().longOpt("to-iter").hasArg().argName("n") - .desc("PBKDF2 iterations for password recipients (default 200000)").build(); + .desc("PBKDF2 iterations for password recipients (default 200000)").get(); final Option OPT_PSW_SALT = Option.builder().longOpt("to-salt-len").hasArg().argName("bytes") - .desc("PBKDF2 salt length for password recipients (default 16)").build(); + .desc("PBKDF2 salt length for password recipients (default 16)").get(); final Option OPT_PSW_KEK = Option.builder().longOpt("to-kek-bytes").hasArg().argName("bytes") - .desc("Derived KEK length for password recipients (default 32)").build(); + .desc("Derived KEK length for password recipients (default 32)").get(); // ---- decoys (all types) final Option OPT_DECOY_ALIAS = Option.builder().longOpt("decoy-alias").hasArg().argName("alias") - .desc("Add a decoy recipient from keyring (repeatable)").build(); + .desc("Add a decoy recipient from keyring (repeatable)").get(); final Option OPT_DECOY_PSW = Option.builder().longOpt("decoy-psw").hasArg().argName("password") - .desc("Add a decoy password recipient (repeatable)").build(); + .desc("Add a decoy password recipient (repeatable)").get(); final Option OPT_DECOY_PSW_RAND = Option.builder().longOpt("decoy-psw-rand").hasArg().argName("n") - .desc("Add N random decoy password recipients").build(); + .desc("Add N random decoy password recipients").get(); // ---- unlock (decrypt) final Option OPT_PRIV_ALIAS = Option.builder().longOpt("priv-alias").hasArg().argName("alias") - .desc("Unlock with private key from keyring").build(); + .desc("Unlock with private key from keyring").get(); final Option OPT_PASSWORD = Option.builder("p").longOpt("password").hasArg().argName("password") - .desc("Unlock with password").build(); + .desc("Unlock with password").get(); options.addOptionGroup(OP); options.addOption(OPT_OUT); diff --git a/app/src/main/java/zeroecho/Kem.java b/app/src/main/java/zeroecho/Kem.java index a817ffb..7d680c1 100644 --- a/app/src/main/java/zeroecho/Kem.java +++ b/app/src/main/java/zeroecho/Kem.java @@ -113,91 +113,91 @@ public final class Kem { // NOPMD /** Encrypt mode: -e|--encrypt <input> */ public static final Option OPT_ENCRYPT = Option.builder("e").longOpt("encrypt").hasArg().argName("input") - .desc("Encrypt the input file").build(); + .desc("Encrypt the input file").get(); /** Decrypt mode: -d|--decrypt <input> */ public static final Option OPT_DECRYPT = Option.builder("d").longOpt("decrypt").hasArg().argName("input") - .desc("Decrypt the input file").build(); + .desc("Decrypt the input file").get(); /** Output path: -o|--output <file> */ public static final Option OPT_OUTPUT = Option.builder("o").longOpt("output").hasArg().argName("file") - .desc("Output file path (default: <input>.enc for encrypt, <input>.dec for decrypt)").build(); + .desc("Output file path (default: <input>.enc for encrypt, <input>.dec for decrypt)").get(); /** Keyring path: -K|--keyring <file> */ public static final Option OPT_KEYRING = Option.builder("K").longOpt("keyring").hasArg().argName("file") - .desc("Path to KeyringStore file").build(); + .desc("Path to KeyringStore file").get(); /** Recipient public alias (encrypt): --pub <alias> */ public static final Option OPT_PUB = Option.builder().longOpt("pub").hasArg().argName("alias") - .desc("Recipient public key alias (encryption)").build(); + .desc("Recipient public key alias (encryption)").get(); /** Recipient private alias (decrypt): --priv <alias> */ public static final Option OPT_PRIV = Option.builder().longOpt("priv").hasArg().argName("alias") - .desc("Recipient private key alias (decryption)").build(); + .desc("Recipient private key alias (decryption)").get(); /** KEM id: --kem <id> */ public static final Option OPT_KEM = Option.builder().longOpt("kem").hasArg().argName("id") - .desc("KEM algorithm id (see --list-kems)").build(); + .desc("KEM algorithm id (see --list-kems)").get(); /** Discovery: --list-kems */ public static final Option OPT_LIST_KEMS = Option.builder().longOpt("list-kems") - .desc("List KEM algorithms that support ENCAPSULATE and DECAPSULATE and exit").build(); + .desc("List KEM algorithms that support ENCAPSULATE and DECAPSULATE and exit").get(); /** Payload switch: --aes */ public static final Option OPT_AES = Option.builder().longOpt("aes") - .desc("Use AES payload (select mode via --aes-cipher)").build(); + .desc("Use AES payload (select mode via --aes-cipher)").get(); /** Payload switch: --chacha */ public static final Option OPT_CHACHA = Option.builder().longOpt("chacha") - .desc("Use ChaCha payload (AEAD if --aad is provided, otherwise stream)").build(); + .desc("Use ChaCha payload (AEAD if --aad is provided, otherwise stream)").get(); /** AAD (hex): --aad <hex> */ public static final Option OPT_AAD = Option.builder().longOpt("aad").hasArg().argName("hex") - .desc("Additional Authenticated Data (hex)").build(); + .desc("Additional Authenticated Data (hex)").get(); /** Header toggle: --header */ public static final Option OPT_HEADER = Option.builder().longOpt("header") - .desc("Write/read a compact symmetric header (IV/AAD/params) when supported").build(); + .desc("Write/read a compact symmetric header (IV/AAD/params) when supported").get(); /** HKDF: --hkdf [infoHex] */ public static final Option OPT_HKDF = Option.builder().longOpt("hkdf").optionalArg(true).hasArg().argName("infoHex") - .desc("Use HKDF-SHA256 for KEM secret; optional info as hex (default internal info)").build(); + .desc("Use HKDF-SHA256 for KEM secret; optional info as hex (default internal info)").get(); /** Direct secret: --direct */ public static final Option OPT_DIRECT = Option.builder().longOpt("direct") - .desc("Use the raw KEM shared secret directly (disable HKDF)").build(); + .desc("Use the raw KEM shared secret directly (disable HKDF)").get(); /** Derived key bytes: --key-bytes <int> */ public static final Option OPT_KEY_BYTES = Option.builder().longOpt("key-bytes").hasArg().argName("int") - .type(Number.class).desc("Derived symmetric key length in bytes (default 32)").build(); + .type(Number.class).desc("Derived symmetric key length in bytes (default 32)").get(); /** Max KEM ciphertext len: --max-kem-ct <int> */ public static final Option OPT_MAX_KEM_CT = Option.builder().longOpt("max-kem-ct").hasArg().argName("int") - .type(Number.class).desc("Maximum accepted KEM ciphertext length in bytes (default 65536)").build(); + .type(Number.class).desc("Maximum accepted KEM ciphertext length in bytes (default 65536)").get(); /** AES mode: --aes-cipher gcm|ctr|cbc */ public static final Option OPT_AES_CIPHER = Option.builder().longOpt("aes-cipher").hasArg().argName("gcm|ctr|cbc") - .desc("AES cipher variant for payload (default gcm)").build(); + .desc("AES cipher variant for payload (default gcm)").get(); /** AES IV: --aes-iv <hex> */ public static final Option OPT_AES_IV = Option.builder().longOpt("aes-iv").hasArg().argName("hex") - .desc("AES IV/nonce (hex)").build(); + .desc("AES IV/nonce (hex)").get(); /** AES tag bits: --aes-tag-bits <int> */ public static final Option OPT_AES_TAG_BITS = Option.builder().longOpt("aes-tag-bits").hasArg().argName("int") - .type(Number.class).desc("AES-GCM authentication tag length in bits (default 128)").build(); + .type(Number.class).desc("AES-GCM authentication tag length in bits (default 128)").get(); /** ChaCha nonce: --chacha-nonce <hex> */ public static final Option OPT_CHACHA_NONCE = Option.builder().longOpt("chacha-nonce").hasArg().argName("hex") - .desc("ChaCha nonce (hex, usually 12 bytes)").build(); + .desc("ChaCha nonce (hex, usually 12 bytes)").get(); /** ChaCha counter value: --chacha-counter <int> */ public static final Option OPT_CHACHA_COUNTER = Option.builder().longOpt("chacha-counter").hasArg().argName("int") - .type(Number.class).desc("ChaCha counter value for stream mode (integer)").build(); + .type(Number.class).desc("ChaCha counter value for stream mode (integer)").get(); /** ChaCha initial counter: --chacha-initial <int> */ public static final Option OPT_CHACHA_INITIAL = Option.builder().longOpt("chacha-initial").hasArg().argName("int") - .type(Number.class).desc("ChaCha initial counter (integer)").build(); + .type(Number.class).desc("ChaCha initial counter (integer)").get(); private Kem() { // no instances diff --git a/app/src/main/java/zeroecho/KeyStoreManagement.java b/app/src/main/java/zeroecho/KeyStoreManagement.java index c28eb80..1eff8ce 100644 --- a/app/src/main/java/zeroecho/KeyStoreManagement.java +++ b/app/src/main/java/zeroecho/KeyStoreManagement.java @@ -167,49 +167,49 @@ public final class KeyStoreManagement { // NOPMD // --------------------------------------------------------------------- private static final Option KEYSTORE_OPTION = Option.builder("k").longOpt("keystore").hasArg().argName("file") - .desc("Path to keyring store").build(); + .desc("Path to keyring store").get(); private static final Option LIST_ALGORITHMS_OPTION = Option.builder().longOpt("list-algorithms") - .desc("List catalog algorithms with symmetric/asymmetric support").build(); + .desc("List catalog algorithms with symmetric/asymmetric support").get(); private static final Option LIST_ALIASES_OPTION = Option.builder().longOpt("list-aliases") - .desc("List aliases present in the keyring").build(); + .desc("List aliases present in the keyring").get(); private static final Option GENERATE_OPTION = Option.builder().longOpt("generate") - .desc("Generate a keypair or a secret").build(); + .desc("Generate a keypair or a secret").get(); private static final Option ALG_OPTION = Option.builder().longOpt("alg").hasArg().argName("id") - .desc("Algorithm id (e.g., RSA, Ed25519, AES, Frodo)").build(); + .desc("Algorithm id (e.g., RSA, Ed25519, AES, Frodo)").get(); private static final Option ALIAS_OPTION = Option.builder().longOpt("alias").hasArg().argName("name") - .desc("Alias base; for asymmetric, two entries will be written").build(); + .desc("Alias base; for asymmetric, two entries will be written").get(); private static final Option KIND_OPTION = Option.builder().longOpt("kind").hasArg().argName("sym|asym") - .desc("Force symmetric or asymmetric when algorithm supports both").build(); + .desc("Force symmetric or asymmetric when algorithm supports both").get(); private static final Option PUB_SUFFIX_OPTION = Option.builder().longOpt("pub-suffix").hasArg().argName("sfx") - .desc("Suffix for public alias (default .pub)").build(); + .desc("Suffix for public alias (default .pub)").get(); private static final Option PRV_SUFFIX_OPTION = Option.builder().longOpt("prv-suffix").hasArg().argName("sfx") - .desc("Suffix for private alias (default .prv)").build(); + .desc("Suffix for private alias (default .prv)").get(); private static final Option OVERWRITE_OPTION = Option.builder().longOpt("overwrite") - .desc("Overwrite existing aliases on conflict").build(); + .desc("Overwrite existing aliases on conflict").get(); private static final Option EXPORT_OPTION = Option.builder().longOpt("export") - .desc("Export selected aliases as a versioned text snippet").build(); + .desc("Export selected aliases as a versioned text snippet").get(); private static final Option IMPORT_OPTION = Option.builder().longOpt("import") - .desc("Import a versioned text snippet into the keyring").build(); + .desc("Import a versioned text snippet into the keyring").get(); private static final Option ALIASES_OPTION = Option.builder().longOpt("aliases").hasArg().argName("a,b,c") - .desc("Comma-separated aliases to export; empty means all").build(); + .desc("Comma-separated aliases to export; empty means all").get(); private static final Option OUTFILE_OPTION = Option.builder().longOpt("out").hasArg().argName("file|-") - .desc("Output file for export (default '-' for stdout)").build(); + .desc("Output file for export (default '-' for stdout)").get(); private static final Option INFILE_OPTION = Option.builder().longOpt("in").hasArg().argName("file|-") - .desc("Input file for import (default '-' for stdin)").build(); + .desc("Input file for import (default '-' for stdin)").get(); /** Prevents instantiation. */ private KeyStoreManagement() { diff --git a/app/src/main/java/zeroecho/Tag.java b/app/src/main/java/zeroecho/Tag.java index 0eec860..6ef1e13 100644 --- a/app/src/main/java/zeroecho/Tag.java +++ b/app/src/main/java/zeroecho/Tag.java @@ -48,10 +48,10 @@ import java.util.Objects; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.DefaultParser; -import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.help.HelpFormatter; import zeroecho.core.alg.digest.DigestSpec; import zeroecho.core.err.VerificationException; @@ -103,28 +103,28 @@ public final class Tag { // NOPMD // ---- All options as constants private static final Option TYPE_OPT = Option.builder().longOpt("type").hasArg().argName("signature|digest") - .desc("tag primitive type").build(); + .desc("tag primitive type").get(); private static final Option MODE_OPT = Option.builder().longOpt("mode").hasArg().argName("produce|verify") - .desc("operation mode").build(); + .desc("operation mode").get(); private static final Option ALG_OPT = Option.builder().longOpt("alg").hasArg().argName("id") - .desc("algorithm id (signature: Ed25519/Ed448/ECDSA/RSA; digest: SHA-256/.../SHAKE256:N)").build(); + .desc("algorithm id (signature: Ed25519/Ed448/ECDSA/RSA; digest: SHA-256/.../SHAKE256:N)").get(); private static final Option KS_OPT = Option.builder().longOpt("ks").hasArg().argName("file") - .desc("keyring file (required for signature)").build(); + .desc("keyring file (required for signature)").get(); private static final Option PRIV_OPT = Option.builder().longOpt("priv").hasArg().argName("alias") - .desc("private key alias (signature + produce)").build(); + .desc("private key alias (signature + produce)").get(); private static final Option PUB_OPT = Option.builder().longOpt("pub").hasArg().argName("alias") - .desc("public key alias (signature + verify)").build(); + .desc("public key alias (signature + verify)").get(); private static final Option IN_OPT = Option.builder().longOpt("in").hasArg().argName("file|-") - .desc("input file or - for STDIN").build(); + .desc("input file or - for STDIN").get(); private static final Option OUT_OPT = Option.builder().longOpt("out").hasArg().argName("file|-") - .desc("output file or - for STDOUT").build(); + .desc("output file or - for STDOUT").get(); // ---- Allowed values and defaults (no enums) private static final String TYPE_SIGNATURE = "signature"; @@ -172,7 +172,7 @@ public final class Tag { // NOPMD if (!has(cli, TYPE_OPT) || !has(cli, MODE_OPT) || !has(cli, ALG_OPT) || !has(cli, IN_OPT) || !has(cli, OUT_OPT)) { - new HelpFormatter().printHelp("zeroecho -T [options]", opts); + HelpFormatter.builder().get().printHelp("zeroecho -T [options]", "", opts, "", false); return 2; } diff --git a/app/src/main/java/zeroecho/ZeroEcho.java b/app/src/main/java/zeroecho/ZeroEcho.java index ef1a2bb..471a83e 100644 --- a/app/src/main/java/zeroecho/ZeroEcho.java +++ b/app/src/main/java/zeroecho/ZeroEcho.java @@ -41,12 +41,12 @@ import java.util.logging.Logger; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.DefaultParser; -import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.MissingOptionException; import org.apache.commons.cli.Option; import org.apache.commons.cli.OptionGroup; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.help.HelpFormatter; import zeroecho.sdk.util.BouncyCastleActivator; @@ -98,8 +98,9 @@ public final class ZeroEcho { * prints the help message. * * @param args command-line arguments passed to the program + * @throws IOException If the output could not be written */ - public static void main(final String[] args) { + public static void main(final String[] args) throws IOException { final int errorCode = mainProcess(args); if (errorCode == 0) { @@ -116,15 +117,16 @@ public final class ZeroEcho { * * @param args command-line arguments passed to the program * @return error-code + * @throws IOException If the output could not be written */ - public static int mainProcess(final String... args) { - final Option KEM_OPTION = Option.builder("E").longOpt("kem").desc("KEM encryption/decryption").build(); + public static int mainProcess(final String... args) throws IOException { + final Option KEM_OPTION = Option.builder("E").longOpt("kem").desc("KEM encryption/decryption").get(); final Option GUARD_OPTION = Option.builder("G").longOpt("guard") - .desc("multi-recipient encryption/decryption (keys+passwords), AES/ChaCha").build(); - final Option KEYSTORE_OPTION = Option.builder("K").longOpt("ksm").desc("key store management").build(); - final Option COVERT_OPTION = Option.builder("C").longOpt("covert").desc("covert channel processing").build(); + .desc("multi-recipient encryption/decryption (keys+passwords), AES/ChaCha").get(); + final Option KEYSTORE_OPTION = Option.builder("K").longOpt("ksm").desc("key store management").get(); + final Option COVERT_OPTION = Option.builder("C").longOpt("covert").desc("covert channel processing").get(); final Option TAG_OPTION = Option.builder("T").longOpt("tag") - .desc("tag subcommand (signature/digest; produce/verify)").build(); + .desc("tag subcommand (signature/digest; produce/verify)").get(); final OptionGroup OPERATION_GROUP = new OptionGroup(); OPERATION_GROUP.addOption(GUARD_OPTION); @@ -186,12 +188,12 @@ public final class ZeroEcho { * @param options The {@link Options} instance defining the available * command-line options. * @return always {@code 1} + * @throws IOException If the output could not be written */ - private static int help(final Options options) { + private static int help(final Options options) throws IOException { // automatically generate the help statement - final HelpFormatter formatter = new HelpFormatter(); - formatter.setWidth(80); - formatter.printHelp(ZeroEcho.class.getName(), options); + final HelpFormatter formatter = HelpFormatter.builder().get(); + formatter.printHelp(ZeroEcho.class.getName(), "", options, "", false); return 1; } diff --git a/app/src/test/java/zeroecho/ZeroEchoTest.java b/app/src/test/java/zeroecho/ZeroEchoTest.java index 45ba976..c61f32e 100644 --- a/app/src/test/java/zeroecho/ZeroEchoTest.java +++ b/app/src/test/java/zeroecho/ZeroEchoTest.java @@ -36,12 +36,14 @@ package zeroecho; import static org.junit.jupiter.api.Assertions.assertEquals; +import java.io.IOException; + import org.junit.jupiter.api.Test; class ZeroEchoTest { @Test - void testAsymetricOptionWithoutParamsReturnsOne() { + void testAsymetricOptionWithoutParamsReturnsOne() throws IOException { System.out.println("testAsymetricOptionWithoutParamsReturnsOne"); int result = ZeroEcho.mainProcess(new String[] { "-A" }); assertEquals(1, result, "Asymetric option without parameters should return 1 (error/help)"); @@ -49,7 +51,7 @@ class ZeroEchoTest { } @Test - void testAesPswOptionWithoutParamsReturnsOne() { + void testAesPswOptionWithoutParamsReturnsOne() throws IOException { System.out.println("testAesPswOptionWithoutParamsReturnsOne"); int result = ZeroEcho.mainProcess(new String[] { "-P" }); assertEquals(1, result, "AES-PSW option without parameters should return 1 (error/help)"); @@ -57,7 +59,7 @@ class ZeroEchoTest { } @Test - void testNoOptionReturnsOne() { + void testNoOptionReturnsOne() throws IOException { System.out.println("testNoOptionReturnsOne"); int result = ZeroEcho.mainProcess(new String[] {}); assertEquals(1, result, "No options should return 1 (error/help)"); @@ -65,7 +67,7 @@ class ZeroEchoTest { } @Test - void testInvalidOptionReturnsOne() { + void testInvalidOptionReturnsOne() throws IOException { System.out.println("testInvalidOptionReturnsOne"); int result = ZeroEcho.mainProcess(new String[] { "-X" }); assertEquals(1, result, "Invalid option should return 1 (error/help)");