Skip to content

Commit cc6e330

Browse files
Refactor of command line argument parsing to single file (#388)
Now command line parsing is broken down into a shared module so it can be reused across samples. This makes samples smaller and reduces bloat. Commit log: * Initial work on simplifying command line parsing * Continued work on simplifying command line parsing * Reformatted samples with, hopefully, the correct clang format setting this times * Another attempt at fixing clang format issues * Adjustments to CommandLineUtils and samples to allow building on Windows and Linux * Adjusted secure_tunnel sample to use AWS String instead of std string * Remove commented out namespace usage in secure_tunnel sample * Adjusted samples command line parser to show input type for commands * Minor command line parsing format fixes * Adjusted based on review feedback * Minor formatting fix * Removed const in main function in samples * Clang format fixes * Added additional command groups * Renamed AddCommonX509Commands utility function
1 parent a245b31 commit cc6e330

File tree

22 files changed

+675
-811
lines changed

22 files changed

+675
-811
lines changed

samples/greengrass/basic_discovery/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ project(basic-discovery CXX)
44

55
file(GLOB SRC_FILES
66
"*.cpp"
7+
"../../utils/CommandLineUtils.cpp"
8+
"../../utils/CommandLineUtils.h"
79
)
810

911
add_executable(${PROJECT_NAME} ${SRC_FILES})

samples/greengrass/basic_discovery/main.cpp

Lines changed: 30 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -14,47 +14,11 @@
1414
#include <iostream>
1515
#include <mutex>
1616

17+
#include "../../utils/CommandLineUtils.h"
18+
1719
using namespace Aws::Crt;
1820
using namespace Aws::Discovery;
1921

20-
static void s_printHelp()
21-
{
22-
fprintf(stdout, "Usage:\n");
23-
fprintf(
24-
stdout,
25-
"basic-discovery --region <optional: region> --cert <path to cert>"
26-
" --key <path to key> --ca_file <optional: path to custom ca>"
27-
" --thing_name <thing name> --topic <optional: topic> "
28-
" --mode <optional: both|publish|subscribe> --message <optional: message to publish>"
29-
" --proxy-host <optional: proxy host name> --proxy-port <optional: proxy port>\n\n");
30-
fprintf(stdout, "region: the region for your green grass groups, default us-east-1\n");
31-
fprintf(stdout, "cert: path to your client certificate in PEM format\n");
32-
fprintf(stdout, "key: path to your key in PEM format\n");
33-
fprintf(stdout, "ca_file: ca file to use in verifying TLS connections.\n");
34-
fprintf(stdout, "\tIt's the path to a CA file in PEM format\n");
35-
fprintf(stdout, "thing_name: the name of your IOT thing\n");
36-
fprintf(stdout, "topic: targeted topic. Default is test/topic\n");
37-
fprintf(stdout, "mode: default both\n");
38-
fprintf(stdout, "message: message to publish. default 'Hello World'\n");
39-
fprintf(stdout, "proxy-host: proxy host to use for discovery call. Default is to not use a proxy.\n");
40-
fprintf(stdout, "proxy-port: proxy port to use for discovery call.\n");
41-
}
42-
43-
bool s_cmdOptionExists(char **begin, char **end, const String &option)
44-
{
45-
return std::find(begin, end, option) != end;
46-
}
47-
48-
char *s_getCmdOption(char **begin, char **end, const String &option)
49-
{
50-
char **itr = std::find(begin, end, option);
51-
if (itr != end && ++itr != end)
52-
{
53-
return *itr;
54-
}
55-
return 0;
56-
}
57-
5822
int main(int argc, char *argv[])
5923
{
6024
/************************ Setup the Lib ****************************/
@@ -75,50 +39,37 @@ int main(int argc, char *argv[])
7539
String message("Hello World");
7640

7741
/*********************** Parse Arguments ***************************/
78-
if (!(s_cmdOptionExists(argv, argv + argc, "--cert") && s_cmdOptionExists(argv, argv + argc, "--key") &&
79-
s_cmdOptionExists(argv, argv + argc, "--thing_name")))
80-
{
81-
s_printHelp();
82-
return 0;
83-
}
84-
85-
certificatePath = s_getCmdOption(argv, argv + argc, "--cert");
86-
keyPath = s_getCmdOption(argv, argv + argc, "--key");
87-
thingName = s_getCmdOption(argv, argv + argc, "--thing_name");
88-
89-
if (s_cmdOptionExists(argv, argv + argc, "--ca_file"))
42+
Utils::CommandLineUtils cmdUtils = Utils::CommandLineUtils();
43+
cmdUtils.RegisterProgramName("basic-discovery");
44+
cmdUtils.AddCommonMQTTCommands();
45+
cmdUtils.AddCommonProxyCommands();
46+
cmdUtils.AddCommonTopicMessageCommands();
47+
cmdUtils.RemoveCommand("endpoint");
48+
cmdUtils.RegisterCommand(
49+
"region", "<str>", "The region for your Greengrass groups (optional, default='us-east-1').");
50+
cmdUtils.RegisterCommand("thing_name", "<str>", "The name of your IOT thing");
51+
cmdUtils.RegisterCommand(
52+
"mode", "<str>", "Mode options: 'both', 'publish', or 'subscribe' (optional, default='both').");
53+
const char **const_argv = (const char **)argv;
54+
cmdUtils.SendArguments(const_argv, const_argv + argc);
55+
56+
if (cmdUtils.HasCommand("help"))
9057
{
91-
caFile = s_getCmdOption(argv, argv + argc, "--ca_file");
92-
}
93-
94-
if (s_cmdOptionExists(argv, argv + argc, "--region"))
95-
{
96-
region = s_getCmdOption(argv, argv + argc, "--region");
97-
}
98-
99-
if (s_cmdOptionExists(argv, argv + argc, "--topic"))
100-
{
101-
topic = s_getCmdOption(argv, argv + argc, "--topic");
102-
}
103-
104-
if (s_cmdOptionExists(argv, argv + argc, "--mode"))
105-
{
106-
mode = s_getCmdOption(argv, argv + argc, "--mode");
107-
}
108-
109-
if (s_cmdOptionExists(argv, argv + argc, "--message"))
110-
{
111-
message = s_getCmdOption(argv, argv + argc, "--message");
112-
}
113-
114-
if (s_cmdOptionExists(argv, argv + argc, "--proxy-host"))
115-
{
116-
proxyHost = s_getCmdOption(argv, argv + argc, "--proxy-host");
58+
cmdUtils.PrintHelp();
59+
exit(-1);
11760
}
118-
119-
if (s_cmdOptionExists(argv, argv + argc, "--proxy-port"))
61+
certificatePath = cmdUtils.GetCommandRequired("cert");
62+
keyPath = cmdUtils.GetCommandRequired("key");
63+
thingName = cmdUtils.GetCommandRequired("thing_name");
64+
caFile = cmdUtils.GetCommandOrDefault("ca_file", caFile);
65+
region = cmdUtils.GetCommandOrDefault("region", region);
66+
topic = cmdUtils.GetCommandOrDefault("topic", topic);
67+
mode = cmdUtils.GetCommandOrDefault("mode", mode);
68+
message = cmdUtils.GetCommandOrDefault("message", message);
69+
proxyHost = cmdUtils.GetCommandOrDefault("proxy_host", proxyHost);
70+
if (cmdUtils.HasCommand("proxy_port"))
12071
{
121-
String portString = s_getCmdOption(argv, argv + argc, "--proxy-port");
72+
String portString = cmdUtils.GetCommand("proxy_port");
12273
proxyPort = static_cast<uint16_t>(atoi(portString.c_str()));
12374
}
12475

samples/greengrass/ipc/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ project(greengrass-ipc CXX)
44

55
file(GLOB SRC_FILES
66
"*.cpp"
7+
"../../utils/CommandLineUtils.cpp"
8+
"../../utils/CommandLineUtils.h"
79
)
810

911
add_executable(${PROJECT_NAME} ${SRC_FILES})

samples/greengrass/ipc/main.cpp

Lines changed: 12 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,14 @@
77

88
#include <aws/greengrass/GreengrassCoreIpcClient.h>
99

10+
#include "../../utils/CommandLineUtils.h"
11+
1012
using namespace Aws::Crt;
1113
using namespace Aws::Greengrass;
1214

13-
static void s_printHelp()
14-
{
15-
fprintf(stdout, "Usage:\n");
16-
fprintf(stdout, "greengrass-ipc --topic <optional: topic> --message <optional: message to publish>\n\n");
17-
fprintf(stdout, "topic: targeted topic. Default is test/topic\n");
18-
fprintf(stdout, "message: message to publish. default 'Hello World'\n");
19-
}
20-
2115
/* Used to check that the publish has been received so that the demo can exit successfully. */
2216
static std::atomic_bool s_publishReceived(false);
2317

24-
bool s_cmdOptionExists(char **begin, char **end, const String &option)
25-
{
26-
return std::find(begin, end, option) != end;
27-
}
28-
29-
char *s_getCmdOption(char **begin, char **end, const String &option)
30-
{
31-
char **itr = std::find(begin, end, option);
32-
if (itr != end && ++itr != end)
33-
{
34-
return *itr;
35-
}
36-
return 0;
37-
}
38-
3918
int main(int argc, char *argv[])
4019
{
4120
/************************ Setup the Lib ****************************/
@@ -48,21 +27,19 @@ int main(int argc, char *argv[])
4827
String message("Hello World");
4928

5029
/*********************** Parse Arguments ***************************/
51-
if (s_cmdOptionExists(argv, argv + argc, "--help"))
52-
{
53-
s_printHelp();
54-
return 0;
55-
}
30+
Utils::CommandLineUtils cmdUtils = Utils::CommandLineUtils();
31+
cmdUtils.RegisterProgramName("greengrass-ipc");
32+
cmdUtils.AddCommonTopicMessageCommands();
33+
const char **const_argv = (const char **)argv;
34+
cmdUtils.SendArguments(const_argv, const_argv + argc);
5635

57-
if (s_cmdOptionExists(argv, argv + argc, "--topic"))
36+
if (cmdUtils.HasCommand("help"))
5837
{
59-
topic = s_getCmdOption(argv, argv + argc, "--topic");
60-
}
61-
62-
if (s_cmdOptionExists(argv, argv + argc, "--message"))
63-
{
64-
message = s_getCmdOption(argv, argv + argc, "--message");
38+
cmdUtils.PrintHelp();
39+
exit(-1);
6540
}
41+
topic = cmdUtils.GetCommandOrDefault("topic", topic);
42+
message = cmdUtils.GetCommandOrDefault("message", message);
6643

6744
/**
6845
* Create the default ClientBootstrap, which will create the default

samples/identity/fleet_provisioning/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ project(fleet-provisioning CXX)
44

55
file(GLOB SRC_FILES
66
"*.cpp"
7+
"../../utils/CommandLineUtils.cpp"
8+
"../../utils/CommandLineUtils.h"
79
)
810

911
add_executable(${PROJECT_NAME} ${SRC_FILES})

samples/identity/fleet_provisioning/main.cpp

Lines changed: 22 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -32,47 +32,13 @@
3232
#include <string>
3333
#include <thread>
3434

35+
#include "../../utils/CommandLineUtils.h"
36+
3537
using namespace Aws::Crt;
3638
using namespace Aws::Iotidentity;
3739
using namespace std::this_thread; // sleep_for, sleep_until
3840
using namespace std::chrono; // nanoseconds, system_clock, seconds
3941

40-
static void s_printHelp()
41-
{
42-
fprintf(stdout, "Usage:\n");
43-
fprintf(
44-
stdout,
45-
"fleet-provisioning --endpoint <endpoint> --ca_file <optional: path to custom ca> --cert <path to cert>"
46-
" --key <path to key> --templateName <template name> --templateParameters <template parameters> --csr "
47-
"<optional: path to csr> \n\n");
48-
fprintf(stdout, "endpoint: the endpoint of the mqtt server not including a port\n");
49-
fprintf(stdout, "cert: path to your client certificate in PEM format\n");
50-
fprintf(stdout, "csr: path to CSR in PEM format\n");
51-
fprintf(stdout, "key: path to your key in PEM format\n");
52-
fprintf(
53-
stdout,
54-
"ca_file: Optional, if the mqtt server uses a certificate that's not already"
55-
" in your trust store, set this.\n");
56-
fprintf(stdout, "\tIt's the path to a CA file in PEM format\n");
57-
fprintf(stdout, "template_name: the name of your provisioning template\n");
58-
fprintf(stdout, "template_parameters: template parameters json\n");
59-
}
60-
61-
static bool s_cmdOptionExists(char **begin, char **end, const String &option)
62-
{
63-
return std::find(begin, end, option) != end;
64-
}
65-
66-
static char *s_getCmdOption(char **begin, char **end, const String &option)
67-
{
68-
char **itr = std::find(begin, end, option);
69-
if (itr != end && ++itr != end)
70-
{
71-
return *itr;
72-
}
73-
return 0;
74-
}
75-
7642
static void sleep(int sleeptime)
7743
{
7844
std::cout << "Sleeping for " << sleeptime << " seconds..." << std::endl;
@@ -110,29 +76,29 @@ int main(int argc, char *argv[])
11076
apiHandle.InitializeLogging(Aws::Crt::LogLevel::Trace, stderr);
11177

11278
/*********************** Parse Arguments ***************************/
113-
if (!(s_cmdOptionExists(argv, argv + argc, "--endpoint") && s_cmdOptionExists(argv, argv + argc, "--cert") &&
114-
s_cmdOptionExists(argv, argv + argc, "--key") && s_cmdOptionExists(argv, argv + argc, "--template_name") &&
115-
s_cmdOptionExists(argv, argv + argc, "--template_parameters")))
79+
Utils::CommandLineUtils cmdUtils = Utils::CommandLineUtils();
80+
cmdUtils.RegisterProgramName("fleet-provisioning");
81+
cmdUtils.AddCommonMQTTCommands();
82+
cmdUtils.RegisterCommand("template_name", "<str>", "The name of your provisioning template");
83+
cmdUtils.RegisterCommand("template_parameters", "<json>", "Template parameters json");
84+
cmdUtils.RegisterCommand("csr", "<path>", "Path to CSR in PEM format (optional)");
85+
const char **const_argv = (const char **)argv;
86+
cmdUtils.SendArguments(const_argv, const_argv + argc);
87+
88+
if (cmdUtils.HasCommand("help"))
11689
{
117-
s_printHelp();
118-
return 0;
119-
}
120-
121-
endpoint = s_getCmdOption(argv, argv + argc, "--endpoint");
122-
certificatePath = s_getCmdOption(argv, argv + argc, "--cert");
123-
keyPath = s_getCmdOption(argv, argv + argc, "--key");
124-
templateName = s_getCmdOption(argv, argv + argc, "--template_name");
125-
templateParameters = s_getCmdOption(argv, argv + argc, "--template_parameters");
126-
127-
if (s_cmdOptionExists(argv, argv + argc, "--ca_file"))
128-
{
129-
caFile = s_getCmdOption(argv, argv + argc, "--ca_file");
90+
cmdUtils.PrintHelp();
91+
exit(-1);
13092
}
131-
132-
// if CSRFile provided
133-
if (s_cmdOptionExists(argv, argv + argc, "--csr"))
93+
endpoint = cmdUtils.GetCommandRequired("endpoint");
94+
certificatePath = cmdUtils.GetCommandRequired("cert");
95+
keyPath = cmdUtils.GetCommandRequired("key");
96+
templateName = cmdUtils.GetCommandRequired("template_name");
97+
templateParameters = cmdUtils.GetCommandRequired("template_parameters");
98+
caFile = cmdUtils.GetCommandOrDefault("ca_file", caFile);
99+
if (cmdUtils.HasCommand("csr"))
134100
{
135-
csrFile = getFileData(s_getCmdOption(argv, argv + argc, "--csr")).c_str();
101+
csrFile = getFileData(cmdUtils.GetCommand("csr").c_str()).c_str();
136102
}
137103

138104
/********************** Now Setup an Mqtt Client ******************/

samples/jobs/describe_job_execution/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ project(describe-job-execution CXX)
44

55
file(GLOB SRC_FILES
66
"*.cpp"
7+
"../../utils/CommandLineUtils.cpp"
8+
"../../utils/CommandLineUtils.h"
79
)
810

911
add_executable(${PROJECT_NAME} ${SRC_FILES})

0 commit comments

Comments
 (0)