Skip to content

CLI parsing

This is the API reference for the CLI parsing surface: the function that turns raw process arguments into a resolved, typed result, and the shape of that result in each SDK. After parsing the raw flags it runs the platform/transport precedence resolver, so the value it returns already carries the two resolved runtime axes plus the resolved config source, identity, and (for MQTT) the messaging-config path.

The parser recognizes the four standard flags (identical across all four SDKs). Any application-specific options are merged in alongside them (Java Options, Python an argparse.ArgumentParser, Rust/TS by composing onto the base command).

Flag Values Default
-c / --config <SOURCE> [args...] FILE | CONFIGMAP | ENV | GG_CONFIG | SHADOW | CONFIG_COMPONENT from the resolved platform profile
--platform <PLATFORM> GREENGRASS | HOST | KUBERNETES | auto auto (auto-detected)
--transport <TRANSPORT> [path] IPC | MQTT [messaging_config.json] derived from the platform
-t / --thing <name> IoT Thing name (full string) resolved from the environment

Platform and transport tokens parse case-insensitively. The removed -m / --mode flag is rejected with guidance to --platform / --transport. See the CLI contract for the per-source extra-argument defaults, the auto-detection order, and the IPC-on-GREENGRASS-only rule.

GGCommons.processArgs is public static. It parses with Apache Commons CLI, rejects -m/--mode, runs the resolver, and returns a ParsedCommandLine.

package com.mbreissi.ggcommons;
// componentName — used for the --help banner
// args — the raw String[] from main(...), WITHOUT the program name
// appOptions — extra application Options to merge (may be null)
public static ParsedCommandLine processArgs(
String componentName, String[] args, Options appOptions)
// Example: parse with no extra application options.
ParsedCommandLine parsed =
GGCommons.processArgs("com.example.MyComponent", args, null);
Platform platform = parsed.platform; // resolved
Transport transport = parsed.transport; // resolved

The parse entry point returns the resolved arguments. The fields are the same idea everywhere, with a few per-language shape differences called out in Cross-language differences.

ParsedCommandLine is a plain public-field data class. thingName is the resolved identity (not the raw -t), and standaloneConfigPath is the MQTT messaging-config path (or null).

package com.mbreissi.ggcommons;
public class ParsedCommandLine {
public CommandLine commandLine; // raw Apache Commons CLI line
public String[] configArgs; // resolved -c source + args (e.g. {"FILE","config.json"})
public Platform platform; // resolved platform
public Transport transport; // resolved transport
public String standaloneConfigPath; // MQTT messaging-config path, or null
public String thingName; // resolved IoT Thing name (identity)
}

The resolved -c source. Rust and TypeScript parse it into a typed value at parse time; Java and Python carry it as the raw token vector (the typed spec genuinely does not exist in those two SDKs).

Java does not type the config source in processArgs. The resolved source and its arguments are the raw String[] ParsedCommandLine.configArgs (for example {"FILE", "config.json"} or {"CONFIGMAP", "/etc/ggcommons", "config.json"}), handed straight to ConfigManagerBuilder downstream.

// No ConfigSourceSpec type in Java — inspect the raw vector:
String[] cfg = parsed.configArgs; // e.g. {"FILE", "config.json"}
String source = cfg[0]; // "FILE" | "CONFIGMAP" | "ENV" | ...

The per-source argument defaults (applied when a positional is omitted) are: FILEconfig.json, ENV → env var CONFIG, GG_CONFIG key → ComponentConfig, CONFIGMAP → dir /etc/ggcommons + key config.json.

These affect only code that inspects the parsed result directly — the flags and their behavior are identical across SDKs.

  • thing vs resolved identity. Rust exposes both thing: Option<String> (raw -t, verbatim) and identity: String (resolved). TypeScript’s ParsedArgs.thing and Java’s ParsedCommandLine.thingName are the resolved identity; the raw -t is not preserved separately. Python’s namespace keeps both (ns.thing raw, ns.identity resolved). Do not assume thing means the raw flag everywhere.
  • Config-source typing. Rust (ConfigSourceSpec enum) and TypeScript (a discriminated union) type the source at parse time; both include CONFIGMAP. Java passes the raw String[] through; Python carries a list[str] and validates the first token against ConfigSource.
  • Messaging-config path placement. Java threads the MQTT messaging-config path through the resolver (its ResolverInputs / ResolvedProfile carry it). Python, Rust, and TypeScript keep those resolver types at four fields and compute the CONFIGMAP-default messaging path in the CLI layer. Either way the resolved path lands on the parsed result (standaloneConfigPath / standalone_config_path / messaging_config_path / messagingConfigPath).
  • Public vs private. Java processArgs, Rust parse_from, and TS parseArgs are public; Python’s _process_args is private — use the builder.
  • -m/--mode rejection breadth. Java and Python reject any token starting with -m or --mode= (so -mSTANDALONE is also caught); Rust and TypeScript reject only the exact tokens -m and --mode.

In normal use the builder calls the parser for you. Hand it the process arguments and read the resolved services (and, where exposed, the parsed args) off the built instance.

import com.mbreissi.ggcommons.GGCommons;
import com.mbreissi.ggcommons.GGCommonsBuilder;
GGCommons gg = GGCommonsBuilder.create("com.example.MyComponent")
.withArgs(args) // runs GGCommons.processArgs internally
.build();
var messaging = gg.getMessaging();
  • CLI contract — the flags, per-platform defaults, auto-detection, and the -m/--mode migration in depth.
  • Configuration guide — what each -c source reads and how hot-reload works.
  • Messaging guide — IPC vs dual-MQTT and the messaging-config file.