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..64056b7 100644
--- a/src/main/java/org/spdx/tools/Verify.java
+++ b/src/main/java/org/spdx/tools/Verify.java
@@ -48,27 +48,47 @@
/**
* Verifies an SPDX document and lists any verification errors
+ *
+ * Exit codes:
+ *
+ * - 0 - the SPDX document is valid
+ * - 1 - the SPDX document is invalid, or could not be read/parsed
+ * - 2 - the command was invoked incorrectly (missing/invalid arguments)
+ *
* @author Gary O'Neall
*/
public class Verify {
static final int MIN_ARGS = 1;
static final int MAX_ARGS = 2;
- 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";
public static final String JSON_SCHEMA_RESOURCE_V3 = "resources/spdx-schema-v3.0.1.json";
-
+
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 +102,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 +110,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 +140,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;
}
}