diff --git a/src/main/java/org/spdx/tools/CompareSpdxDocs.java b/src/main/java/org/spdx/tools/CompareSpdxDocs.java index fdc9629..984c1f8 100644 --- a/src/main/java/org/spdx/tools/CompareSpdxDocs.java +++ b/src/main/java/org/spdx/tools/CompareSpdxDocs.java @@ -44,37 +44,63 @@ * where output.xls is a file name for the output spreadsheet file * and docX are SPDX document files to compare or directories containing SPDX documents. * Document files can be either in RDF/XML or tag/value format + *
+ * Exit codes: + * * * @author Gary O'Neall */ public class CompareSpdxDocs { static final int MIN_ARGS = 2; static final int MAX_ARGS = MultiDocumentSpreadsheet.MAX_DOCUMENTS + 1; + /** + * @deprecated unused - retained for binary/source compatibility, use {@link ExitCode} instead + */ + @Deprecated static final int ERROR_STATUS = 1; static final Logger logger = LoggerFactory.getLogger(CompareSpdxDocs.class); /** + * Main entry point for the CompareSpdxDocs tool. + * Delegates to {@link #run(String[])} and terminates the JVM with its exit status. + * * @param args args[0] is the output Excel file name, all other args are SPDX document file names */ public static void main(String[] args) { + System.exit(run(args)); + } + + /** + * Runs the CompareSpdxDocs command logic and reports results to standard + * out, without terminating the JVM - allows the logic to be unit tested. + * + * @param args args[0] is the output Excel file name, all other args are SPDX document file names + * @return process exit status, see {@link ExitCode} + */ + static int run(String[] args) { if (args.length < MIN_ARGS) { System.out.println("Insufficient arguments"); usage(); - System.exit(ERROR_STATUS); + return ExitCode.USAGE_ERROR; } if (args.length > MAX_ARGS) { System.out.println("Too many SPDX documents specified. Must be less than "+String.valueOf(MAX_ARGS-1)+" document filenames"); usage(); - System.exit(ERROR_STATUS); + return ExitCode.USAGE_ERROR; } SpdxToolsHelper.initialize(); try { onlineFunction(args); } catch (OnlineToolException e){ System.out.println(e.getMessage()); - System.exit(ERROR_STATUS); + return ExitCode.ERROR; } + return ExitCode.SUCCESS; } /** diff --git a/src/main/java/org/spdx/tools/ExitCode.java b/src/main/java/org/spdx/tools/ExitCode.java new file mode 100644 index 0000000..98b8a3b --- /dev/null +++ b/src/main/java/org/spdx/tools/ExitCode.java @@ -0,0 +1,43 @@ +/** + * SPDX-FileCopyrightText: 2026 SPDX Contributors + * SPDX-FileType: SOURCE + * SPDX-License-Identifier: Apache-2.0 + */ +package org.spdx.tools; + +/** + * Shared process exit status codes for the command line tools. + *
+ * Individual tools are free to only use a subset of these - e.g. a tool + * with no document-level validity concept may only ever return + * {@link #SUCCESS} or {@link #ERROR}. + *
+ * Values match the {@code CommandLine.ExitCode} constants used by + * picocli, a common Java CLI framework + * ({@code OK=0}, {@code SOFTWARE=1}, {@code USAGE=2}). + * + * @author Arthit Suriyawongkul + */ +public class ExitCode { + + private ExitCode() { + // Static constants only, no instances + } + + /** + * The command completed successfully. + */ + public static final int SUCCESS = 0; + + /** + * The command failed - e.g. the SPDX document is invalid, or could + * not be read/parsed. + */ + public static final int ERROR = 1; + + /** + * The command was invoked incorrectly - e.g. missing or invalid + * arguments. + */ + public static final int USAGE_ERROR = 2; +} diff --git a/src/main/java/org/spdx/tools/Verify.java b/src/main/java/org/spdx/tools/Verify.java index 00ff30e..c627340 100644 --- a/src/main/java/org/spdx/tools/Verify.java +++ b/src/main/java/org/spdx/tools/Verify.java @@ -48,12 +48,23 @@ /** * Verifies an SPDX document and lists any verification errors + *
+ * Exit codes: + * * @author Gary O'Neall */ public class Verify { static final int MIN_ARGS = 1; static final int MAX_ARGS = 2; + /** + * @deprecated unused - retained for compatibility, use {@link ExitCode} instead + */ + @Deprecated static final int ERROR_STATUS = 1; public static final String JSON_SCHEMA_RESOURCE_V2_3 = "resources/spdx-schema-v2.3.json"; public static final String JSON_SCHEMA_RESOURCE_V2_2 = "resources/spdx-schema-v2.2.json"; @@ -62,13 +73,26 @@ public class Verify { static final ObjectMapper JSON_MAPPER = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); /** + * Main entry point for the Verify tool + * * @param args args[0] SPDX file path; args[1] [RDFXML|JSON|XLS|XLSX|YAML|TAG] an optional file type - if not present, file type of the to file will be used */ public static void main(String[] args) { + System.exit(run(args)); + } + + /** + * Runs the Verify command logic and reports results to standard out/error, + * without terminating the JVM - allows the logic to be unit tested. + * + * @param args args[0] SPDX file path; args[1] [RDFXML|JSON|XLS|XLSX|YAML|TAG] an optional file type - if not present, file type of the to file will be used + * @return process exit status, see {@link ExitCode} + */ + static int run(String[] args) { if (args.length < MIN_ARGS) { System.err .println("Usage:\n Verify file\nwhere file is the file path to an SPDX file"); - System.exit(ERROR_STATUS); + return ExitCode.USAGE_ERROR; } if (args.length > MAX_ARGS) { System.out.println("Warning: Extra arguments will be ignored"); @@ -82,7 +106,7 @@ public static void main(String[] args) { fileType = SpdxToolsHelper.strToFileType(args[1]); } catch (Exception ex) { System.err.println("Invalid file type: "+args[1]); - System.exit(ERROR_STATUS); + return ExitCode.USAGE_ERROR; } } else { fileType = SpdxToolsHelper.fileToFileType(new File(args[0])); @@ -90,10 +114,10 @@ public static void main(String[] args) { verify = verify(args[0], fileType); } catch (SpdxVerificationException e) { System.out.println(e.getMessage()); - System.exit(ERROR_STATUS); + return ExitCode.ERROR; } catch (InvalidFileNameException e) { System.err.println("Invalid file name: "+args[0]); - System.exit(ERROR_STATUS); + return ExitCode.USAGE_ERROR; } // separate out the warning from errors List warnings = new ArrayList<>(); @@ -120,8 +144,9 @@ public static void main(String[] args) { } if (errors.isEmpty()) { System.out.println("This SPDX Document is valid."); + return ExitCode.SUCCESS; } else { - System.exit(ERROR_STATUS); + return ExitCode.ERROR; } }