Skip to content

Commit

Permalink
chore: Add version detection and --version option.
Browse files Browse the repository at this point in the history
Since the header that contains the version is going to change quite
often, make a separate configured header file for it to avoid
triggering huge rebuilds when moving between adjacent commits. It
should trigger only `conf.cpp` to be rebuilt.

Signed-off-by: Kristian Amlie <[email protected]>
  • Loading branch information
Kristian Amlie committed Aug 16, 2023
1 parent 5abd02c commit 4f1ab8a
Show file tree
Hide file tree
Showing 13 changed files with 88 additions and 33 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
/install-sh
/libtool
/ltmain.sh
/mender-version.h
/missing
/stamp-h1
/m4/
Expand Down
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ if (POLICY CMP0135)
cmake_policy(SET CMP0135 NEW)
endif (POLICY CMP0135)

execute_process(
COMMAND sh -c "git describe --tags --dirty --exact-match || git rev-parse --short HEAD"
OUTPUT_VARIABLE MENDER_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
configure_file(mender-version.h.in mender-version.h)

project(mender)

include(cmake/asan.cmake)
Expand Down
2 changes: 2 additions & 0 deletions common/conf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ namespace error = mender::common::error;
namespace expected = mender::common::expected;
namespace cfg_parser = mender::common::config_parser;

extern const string kMenderVersion;

enum ConfigErrorCode {
NoError = 0,
InvalidOptionsError,
Expand Down
26 changes: 23 additions & 3 deletions common/conf/conf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include <cstdlib>
#include <cerrno>

#include <mender-version.h>

#include <common/error.hpp>
#include <common/expected.hpp>
#include <common/conf/paths.hpp>
Expand All @@ -34,6 +36,8 @@ namespace expected = mender::common::expected;
namespace log = mender::common::log;
namespace json = mender::common::json;

const string kMenderVersion = MENDER_VERSION;

const ConfigErrorCategoryClass ConfigErrorCategory;

const char *ConfigErrorCategoryClass::name() const noexcept {
Expand All @@ -46,9 +50,9 @@ string ConfigErrorCategoryClass::message(int code) const {
return "Success";
case InvalidOptionsError:
return "Invalid options given";
default:
return "Unknown";
}
assert(false);
return "Unknown";
}

error::Error MakeError(ConfigErrorCode code, const string &msg) {
Expand Down Expand Up @@ -162,10 +166,13 @@ expected::ExpectedSize MenderConfig::ProcessCmdlineArgs(
"-L",
"--log-level",
"-l"},
{});
{"--version", "-v"});
opts_iter.SetArgumentsMode(ArgumentsMode::StopAtBareArguments);
auto ex_opt_val = opts_iter.Next();
int arg_count = 0;
bool version_arg = false;
while (ex_opt_val && ((ex_opt_val.value().option != "") || (ex_opt_val.value().value != ""))) {
arg_count++;
auto opt_val = ex_opt_val.value();
if ((opt_val.option == "--config") || (opt_val.option == "-c")) {
config_path = opt_val.value;
Expand All @@ -179,13 +186,26 @@ expected::ExpectedSize MenderConfig::ProcessCmdlineArgs(
log_file = opt_val.value;
} else if ((opt_val.option == "--log-level") || (opt_val.option == "-l")) {
log_level = opt_val.value;
} else if ((opt_val.option == "--version") || (opt_val.option == "-v")) {
version_arg = true;
}
ex_opt_val = opts_iter.Next();
}
if (!ex_opt_val) {
return expected::unexpected(ex_opt_val.error());
}

if (version_arg) {
if (arg_count > 1 || opts_iter.GetPos() < static_cast<size_t>(end - start)) {
return expected::unexpected(error::Error(
make_error_condition(errc::invalid_argument),
"--version can not be combined with other commands and arguments"));
} else {
cout << kMenderVersion << endl;
return expected::unexpected(error::MakeError(error::ExitWithSuccessError, ""));
}
}

if (log_file != "") {
auto err = log::SetupFileLogging(log_file, true);
if (error::NoError != err) {
Expand Down
10 changes: 8 additions & 2 deletions common/error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

#include <common/error.hpp>

#include <cassert>

namespace mender {
namespace common {
namespace error {
Expand All @@ -38,9 +40,13 @@ std::string CommonErrorCategoryClass::message(int code) const {
return "Programming error, should not happen";
case GenericError:
return "Unspecified error code";
default:
return "Unknown";
case ExitWithFailureError:
return "ExitWithFailureError";
case ExitWithSuccessError:
return "ExitWithSuccessError";
}
assert(false);
return "Unknown";
}

std::ostream &operator<<(std::ostream &os, const Error &err) {
Expand Down
5 changes: 5 additions & 0 deletions common/error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ enum ErrorCode {
ErrorCodeNoError, // Conflicts with above name, we don't really need it so prefix it.
ProgrammingError,
GenericError, // For when you have no underlying error code, provide message instead.
// Means that we do have an error, but don't print anything. Used for errors where the cli
// already prints a nicely formatted message.
ExitWithFailureError,
// Means that we want to prevent further processing. Used for `--version` option.
ExitWithSuccessError,
};

class CommonErrorCategoryClass : public std::error_category {
Expand Down
28 changes: 20 additions & 8 deletions mender-auth/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,28 +95,25 @@ static actions::ExpectedActionPtr ParseUpdateArguments(
}
}

int main(int argc, char *argv[]) {
error::Error DoMain(int argc, char *argv[]) {
setup::GlobalSetup();

conf::MenderConfig config;
if (argc > 1) {
vector<string> args(argv + 1, argv + argc);
auto arg_pos = config.ProcessCmdlineArgs(args.begin(), args.end());
if (!arg_pos) {
cerr << "Failed to process command line options: " + arg_pos.error().String() << endl;
return 1;
return arg_pos.error();
}

auto action = ParseUpdateArguments(args.begin() + arg_pos.value(), args.end());
if (!action) {
cerr << "Failed to process command line options: " + action.error().String() << endl;
return 1;
return action.error();
}
} else {
auto err = config.LoadDefaults();
if (err != error::NoError) {
cerr << "Failed to process command line options: " + err.String() << endl;
return 1;
return err;
}
}

Expand All @@ -130,11 +127,26 @@ int main(int argc, char *argv[]) {
if (err != error::NoError) {
mlog::Error("Failed to start the listen loop");
mlog::Error(err.String());
return 1;
return error::MakeError(error::ExitWithFailureError, "");
}

loop.Run();
mlog::Info("Finished running the main loop!");

return error::NoError;
}

int main(int argc, char *argv[]) {
auto err = DoMain(argc, argv);

if (err != error::NoError) {
if (err.code == error::MakeError(error::ExitWithSuccessError, "").code) {
return 0;
} else if (err.code != error::MakeError(error::ExitWithFailureError, "").code) {
cerr << "Failed to process command line options: " + err.String() << endl;
}
return 1;
}

return 0;
}
2 changes: 1 addition & 1 deletion mender-update/cli/actions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ static error::Error ResultHandler(standalone::ResultAndError result) {
if (result.err != error::NoError) {
log::Error(result.err.String());
} else {
result.err = context::MakeError(context::ExitStatusOnlyError, "");
result.err = error::MakeError(error::ExitWithFailureError, "");
}
break;
}
Expand Down
23 changes: 14 additions & 9 deletions mender-update/cli/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,21 +124,19 @@ ExpectedActionPtr ParseUpdateArguments(
}
}

int Main(
static error::Error DoMain(
const vector<string> &args,
function<void(mender::update::context::MenderContext &ctx)> test_hook) {
mender::common::conf::MenderConfig config;

auto args_pos = config.ProcessCmdlineArgs(args.begin(), args.end());
if (!args_pos) {
cerr << "Failed to process command line options: " + args_pos.error().String() << endl;
return 1;
return args_pos.error();
}

auto action = ParseUpdateArguments(args.begin() + args_pos.value(), args.end());
if (!action) {
cerr << "Failed to process command line options: " + action.error().String() << endl;
return 1;
return action.error();
}

mender::update::context::MenderContext main_context(config);
Expand All @@ -147,18 +145,25 @@ int Main(

auto err = main_context.Initialize();
if (error::NoError != err) {
cerr << "Failed to intialize main context: " + err.String() << endl;
return 1;
return err;
}

err = action.value()->Execute(main_context);
return action.value()->Execute(main_context);
}

int Main(
const vector<string> &args,
function<void(mender::update::context::MenderContext &ctx)> test_hook) {
auto err = DoMain(args, test_hook);

if (err.code == context::MakeError(context::NoUpdateInProgressError, "").code) {
return NoUpdateInProgressExitStatus;
} else if (err.code == context::MakeError(context::RebootRequiredError, "").code) {
return RebootExitStatus;
} else if (err != error::NoError) {
if (err.code != context::MakeError(context::ExitStatusOnlyError, "").code) {
if (err.code == error::MakeError(error::ExitWithSuccessError, "").code) {
return 0;
} else if (err.code != error::MakeError(error::ExitWithFailureError, "").code) {
cerr << "Could not fulfill request: " + err.String() << endl;
}
return 1;
Expand Down
10 changes: 5 additions & 5 deletions mender-update/cli/cli_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ TEST(CliTest, NoAction) {
EXPECT_EQ(cli::Main(args), 1);
EXPECT_EQ(
redirect_output.GetCerr(),
"Failed to process command line options: Invalid options given: Need an action\n");
"Could not fulfill request: Invalid options given: Need an action\n");
}
}

Expand Down Expand Up @@ -100,7 +100,7 @@ TEST(CliTest, ShowArtifactErrors) {
EXPECT_EQ(cli::Main(args), 1);
EXPECT_EQ(
redirect_output.GetCerr(),
"Failed to process command line options: Invalid options given: Unrecognized option '--bogus-option'\n");
"Could not fulfill request: Invalid options given: Unrecognized option '--bogus-option'\n");
}

{
Expand All @@ -109,7 +109,7 @@ TEST(CliTest, ShowArtifactErrors) {
EXPECT_EQ(cli::Main(args), 1);
EXPECT_EQ(
redirect_output.GetCerr(),
"Failed to process command line options: Invalid options given: Unexpected argument 'bogus-argument'\n");
"Could not fulfill request: Invalid options given: Unexpected argument 'bogus-argument'\n");
}
}

Expand Down Expand Up @@ -219,7 +219,7 @@ TEST(CliTest, ShowProvidesErrors) {
EXPECT_EQ(cli::Main(args), 1);
EXPECT_EQ(
redirect_output.GetCerr(),
"Failed to process command line options: Invalid options given: Unrecognized option '--bogus-option'\n");
"Could not fulfill request: Invalid options given: Unrecognized option '--bogus-option'\n");
}

{
Expand All @@ -228,7 +228,7 @@ TEST(CliTest, ShowProvidesErrors) {
EXPECT_EQ(cli::Main(args), 1);
EXPECT_EQ(
redirect_output.GetCerr(),
"Failed to process command line options: Invalid options given: Unexpected argument 'bogus-argument'\n");
"Could not fulfill request: Invalid options given: Unexpected argument 'bogus-argument'\n");
}
}

Expand Down
3 changes: 0 additions & 3 deletions mender-update/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,6 @@ enum MenderContextErrorCode {
DatabaseValueError,
RebootRequiredError,
NoUpdateInProgressError,
// Means that we do have an error, but don't print anything. Used for errors where the cli
// already prints a nicely formatted message.
ExitStatusOnlyError,
UnexpectedHttpResponse,
StateDataStoreCountExceededError,
};
Expand Down
2 changes: 0 additions & 2 deletions mender-update/context/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,6 @@ string MenderContextErrorCategoryClass::message(int code) const {
return "Reboot required";
case NoUpdateInProgressError:
return "No update in progress";
case ExitStatusOnlyError:
return "ExitStatusOnlyError";
case UnexpectedHttpResponse:
return "Unexpected HTTP response";
case StateDataStoreCountExceededError:
Expand Down
1 change: 1 addition & 0 deletions mender-version.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#cmakedefine MENDER_VERSION "@MENDER_VERSION@"

0 comments on commit 4f1ab8a

Please sign in to comment.