Skip to content

Commit

Permalink
Merge 8cd8d2d into c86b308
Browse files Browse the repository at this point in the history
  • Loading branch information
ahenroid committed Aug 8, 2016
2 parents c86b308 + 8cd8d2d commit dbfddf7
Show file tree
Hide file tree
Showing 71 changed files with 1,882 additions and 367 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,10 @@ enable_cppcheck()
# Pull in helper macros for working with leatherman libraries
include(leatherman)

file(GLOB_RECURSE ALL_SOURCES lib/src/*.cc lib/inc/*.hpp lib/inc/version.h exe/*.cc exe/*.hpp exe/*.h)
add_subdirectory(lib)
add_subdirectory(exe)
add_subdirectory(locales)

# Add test executables for unit testing
add_test(NAME "libfacter\\ tests" COMMAND libfacter_test)
Expand Down
3 changes: 2 additions & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ install:

- choco install mingw-w64 -y -Version 4.8.3 -source https://www.myget.org/F/puppetlabs
- choco install cmake -y -Version 3.2.2 -source https://www.myget.org/F/puppetlabs
- SET PATH=C:\Ruby21-x64\bin;C:\tools\mingw64\bin;%PATH%
- choco install -y gettext -Version 0.19.6 -source https://www.myget.org/F/puppetlabs
- SET PATH=C:\Ruby21-x64\bin;C:\tools\mingw64\bin;C:\Program Files\gettext-iconv;%PATH%
- ps: $env:PATH = $env:PATH.Replace("Git\bin", "Git\cmd")
- ps: $env:PATH = $env:PATH.Replace("Git\usr\bin", "Git\cmd")

Expand Down
144 changes: 73 additions & 71 deletions exe/facter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,36 +32,38 @@ using namespace facter::logging;
using leatherman::util::environment;
namespace po = boost::program_options;

// Mark string for translation (alias for facter::logging::format)
using facter::logging::_;

void help(po::options_description& desc)
{
boost::nowide::cout <<
"Synopsis\n"
"========\n"
"\n"
"Collect and display facts about the system.\n"
"\n"
"Usage\n"
"=====\n"
"\n"
" facter [options] [query] [query] [...]\n"
"\n"
"Options\n"
"=======\n\n" << desc <<
"\nDescription\n"
"===========\n"
"\n"
"Collect and display facts about the current system. The library behind\n"
"facter is easy to extend, making facter an easy way to collect information\n"
"about a system.\n"
"\n"
"If no queries are given, then all facts will be returned.\n"
"\n"
"Example Queries\n"
"===============\n\n"
" facter kernel\n"
" facter networking.ip\n"
" facter processors.models.0" << endl;
_("Synopsis\n"
"========\n"
"\n"
"Collect and display facts about the system.\n"
"\n"
"Usage\n"
"=====\n"
"\n"
" facter [options] [query] [query] [...]\n"
"\n"
"Options\n"
"=======\n\n"
"{1}\nDescription\n"
"===========\n"
"\n"
"Collect and display facts about the current system. The library behind\n"
"facter is easy to extend, making facter an easy way to collect information\n"
"about a system.\n"
"\n"
"If no queries are given, then all facts will be returned.\n"
"\n"
"Example Queries\n"
"===============\n\n"
" facter kernel\n"
" facter networking.ip\n"
" facter processors.models.0", desc) << endl;
}

void log_command_line(int argc, char** argv)
Expand All @@ -76,7 +78,7 @@ void log_command_line(int argc, char** argv)
}
command_line << argv[i];
}
log(level::info, "executed with command line: %1%.", command_line.str());
log(level::info, "executed with command line: {1}.", command_line.str());
}

void log_queries(set<string> const& queries)
Expand All @@ -100,7 +102,7 @@ void log_queries(set<string> const& queries)
}
output << query;
}
log(level::info, "requested queries: %1%.", output.str());
log(level::info, "requested queries: {1}.", output.str());
}

int main(int argc, char **argv)
Expand All @@ -122,25 +124,25 @@ int main(int argc, char **argv)
// Keep this list sorted alphabetically
po::options_description visible_options("");
visible_options.add_options()
("color", "Enables color output.")
("config,c", po::value<string>(&conf_dir), "Specify the location of the config file.")
("custom-dir", po::value<vector<string>>(&custom_directories), "A directory to use for custom facts.")
("debug,d", po::bool_switch()->default_value(false), "Enable debug output.")
("external-dir", po::value<vector<string>>(&external_directories), "A directory to use for external facts.")
("help,h", "Print this help message.")
("json,j", "Output in JSON format.")
("show-legacy", "Show legacy facts when querying all facts.")
("log-level,l", po::value<level>()->default_value(level::warning, "warn"), "Set logging level.\nSupported levels are: none, trace, debug, info, warn, error, and fatal.")
("no-color", "Disables color output.")
("no-custom-facts", po::bool_switch()->default_value(false), "Disables custom facts.")
("no-external-facts", po::bool_switch()->default_value(false), "Disables external facts.")
("no-ruby", po::bool_switch()->default_value(false), "Disables loading Ruby, facts requiring Ruby, and custom facts.")
("puppet,p", "(Deprecated: use `puppet facts` instead) Load the Puppet libraries, thus allowing Facter to load Puppet-specific facts.")
("trace", po::bool_switch()->default_value(false), "Enable backtraces for custom facts.")
("verbose", po::bool_switch()->default_value(false), "Enable verbose (info) output.")
("version,v", "Print the version and exit.")
("yaml,y", "Output in YAML format.")
("strict", "Enables more aggressive error reporting.");
("color", _("Enables color output.").c_str())
("config,c", po::value<string>(&conf_dir), _("Specify the location of the config file.").c_str())
("custom-dir", po::value<vector<string>>(&custom_directories), _("A directory to use for custom facts.").c_str())
("debug,d", po::bool_switch()->default_value(false), _("Enable debug output.").c_str())
("external-dir", po::value<vector<string>>(&external_directories), _("A directory to use for external facts.").c_str())
("help,h", _("Print this help message.").c_str())
("json,j", _("Output in JSON format.").c_str())
("show-legacy", _("Show legacy facts when querying all facts.").c_str())
("log-level,l", po::value<level>()->default_value(level::warning, "warn"), _("Set logging level.\nSupported levels are: none, trace, debug, info, warn, error, and fatal.").c_str())
("no-color", _("Disables color output.").c_str())
("no-custom-facts", po::bool_switch()->default_value(false), _("Disables custom facts.").c_str())
("no-external-facts", po::bool_switch()->default_value(false), _("Disables external facts.").c_str())
("no-ruby", po::bool_switch()->default_value(false), _("Disables loading Ruby, facts requiring Ruby, and custom facts.").c_str())
("puppet,p", _("(Deprecated: use `puppet facts` instead) Load the Puppet libraries, thus allowing Facter to load Puppet-specific facts.").c_str())
("trace", po::bool_switch()->default_value(false), _("Enable backtraces for custom facts.").c_str())
("verbose", po::bool_switch()->default_value(false), _("Enable verbose (info) output.").c_str())
("version,v", _("Print the version and exit.").c_str())
("yaml,y", _("Output in YAML format.").c_str())
("strict", _("Enables more aggressive error reporting.").c_str());

// Build a list of "hidden" options that are not visible on the command line
po::options_description hidden_options("");
Expand All @@ -158,15 +160,15 @@ int main(int argc, char **argv)
// Build a list of options that can be set in the config file
po::options_description config_file_options("");
config_file_options.add_options()
("custom-dir", po::value<vector<string>>(&custom_directories), "A directory to use for custom facts.")
("debug", po::value<bool>(), "Enable debug output.")
("external-dir", po::value<vector<string>>(&external_directories), "A directory to use for external facts.")
("log-level", po::value<level>()->default_value(level::warning, "warn"), "Set logging level.\nSupported levels are: none, trace, debug, info, warn, error, and fatal.")
("no-custom-facts", po::value<bool>(), "Disables custom facts.")
("no-external-facts", po::value<bool>(), "Disables external facts.")
("no-ruby", po::value<bool>(), "Disables loading Ruby, facts requiring Ruby, and custom facts.")
("trace", po::value<bool>(), "Enable backtraces for custom facts.")
("verbose", po::value<bool>(), "Enable verbose (info) output.");
("custom-dir", po::value<vector<string>>(&custom_directories), _("A directory to use for custom facts.").c_str())
("debug", po::value<bool>(), _("Enable debug output.").c_str())
("external-dir", po::value<vector<string>>(&external_directories), _("A directory to use for external facts.").c_str())
("log-level", po::value<level>()->default_value(level::warning, "warn"), _("Set logging level.\nSupported levels are: none, trace, debug, info, warn, error, and fatal.").c_str())
("no-custom-facts", po::value<bool>(), _("Disables custom facts.").c_str())
("no-external-facts", po::value<bool>(), _("Disables external facts.").c_str())
("no-ruby", po::value<bool>(), _("Disables loading Ruby, facts requiring Ruby, and custom facts.").c_str())
("trace", po::value<bool>(), _("Enable backtraces for custom facts.").c_str())
("verbose", po::value<bool>(), _("Enable verbose (info) output.").c_str());

po::variables_map vm;
try {
Expand Down Expand Up @@ -200,41 +202,41 @@ int main(int argc, char **argv)

// Check for conflicting options
if (vm.count("color") && vm.count("no-color")) {
throw po::error("color and no-color options conflict: please specify only one.");
throw po::error(_("color and no-color options conflict: please specify only one."));
}
if (vm.count("json") && vm.count("yaml")) {
throw po::error("json and yaml options conflict: please specify only one.");
throw po::error(_("json and yaml options conflict: please specify only one."));
}
if (vm["no-external-facts"].as<bool>() && vm.count("external-dir")) {
throw po::error("no-external-facts and external-dir options conflict: please specify only one.");
throw po::error(_("no-external-facts and external-dir options conflict: please specify only one."));
}
if (vm["no-custom-facts"].as<bool>() && vm.count("custom-dir")) {
throw po::error("no-custom-facts and custom-dir options conflict: please specify only one.");
throw po::error(_("no-custom-facts and custom-dir options conflict: please specify only one."));
}
if ((vm["debug"].as<bool>() + vm["verbose"].as<bool>() + (vm["log-level"].defaulted() ? 0 : 1)) > 1) {
throw po::error("debug, verbose, and log-level options conflict: please specify only one.");
throw po::error(_("debug, verbose, and log-level options conflict: please specify only one."));
}
if (vm["no-ruby"].as<bool>() && vm.count("custom-dir")) {
throw po::error("no-ruby and custom-dir options conflict: please specify only one.");
throw po::error(_("no-ruby and custom-dir options conflict: please specify only one."));
}
if (vm.count("puppet") && vm["no-custom-facts"].as<bool>()) {
throw po::error("puppet and no-custom-facts options conflict: please specify only one.");
throw po::error(_("puppet and no-custom-facts options conflict: please specify only one."));
}
if (vm.count("puppet") && vm["no-ruby"].as<bool>()) {
throw po::error("puppet and no-ruby options conflict: please specify only one.");
throw po::error(_("puppet and no-ruby options conflict: please specify only one."));
}
}
catch (exception& ex) {
colorize(boost::nowide::cerr, level::error);
boost::nowide::cerr << "error: " << ex.what() << "\n" << endl;
boost::nowide::cerr << _("error: {1}", ex.what()) << endl;
colorize(boost::nowide::cerr);
help(visible_options);
return EXIT_FAILURE;
}

// Check for printing the version
if (vm.count("version")) {
boost::nowide::cout << LIBFACTER_VERSION_WITH_COMMIT << endl;
boost::nowide::cout << _(LIBFACTER_VERSION_WITH_COMMIT) << endl;
return EXIT_SUCCESS;
}

Expand Down Expand Up @@ -311,22 +313,22 @@ int main(int argc, char **argv)
}

// Output the facts
format fmt = format::hash;
facter::facts::format fmt = facter::facts::format::hash;
if (vm.count("json")) {
fmt = format::json;
fmt = facter::facts::format::json;
} else if (vm.count("yaml")) {
fmt = format::yaml;
fmt = facter::facts::format::yaml;
}

bool show_legacy = vm.count("show-legacy");
bool strict_errors = vm.count("strict");
facts.write(boost::nowide::cout, fmt, queries, show_legacy, strict_errors);
boost::nowide::cout << endl;
} catch (locale_error const& e) {
boost::nowide::cerr << "failed to initialize logging system due to a locale error: " << e.what() << "\n" << endl;
boost::nowide::cerr << _("failed to initialize logging system due to a locale error: {1}", e.what()) << endl;
return 2; // special error code to indicate we failed harder than normal
} catch (exception& ex) {
log(level::fatal, "unhandled exception: %1%", ex.what());
log(level::fatal, "unhandled exception: {1}", ex.what());
}

return error_logged() ? EXIT_FAILURE : EXIT_SUCCESS;
Expand Down
64 changes: 38 additions & 26 deletions lib/inc/facter/logging/logging.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,47 +114,59 @@ namespace facter { namespace logging {
LIBFACTER_EXPORT void clear_logged_errors();

/**
* Logs a given message.
* @param lvl The logging level to log with.
* @param message The message to log.
* Translate text using the locale initialized by this library.
* @param msg The string to translate.
* @return The translated string.
*/
LIBFACTER_EXPORT void log(level lvl, std::string const& message);
LIBFACTER_EXPORT std::string translate(std::string const& msg);

/**
* Logs a given format message.
* @param lvl The logging level to log with.
* @param message The message being formatted.
* Format a text message.
* @tparam TArgs The format argument types.
* @param fmt The format string.
* @param args The format arguments.
* @return The formatted string.
*/
LIBFACTER_EXPORT void log(level lvl, boost::format& message);
template <typename... TArgs>
std::string format(std::string const& fmt, TArgs... args)
{
boost::format msg{translate(fmt)};
(void) std::initializer_list<int>{ ((void)(msg % args), 0)... };
return msg.str();
}

/**
* Logs a given format message.
* @tparam T The type of the first argument.
* @tparam TArgs The types of the remaining arguments.
* @param lvl The logging level to log with.
* @param message The message being formatted.
* @param arg The first argument to the message.
* @param args The remaining arguments to the message.
* Format a text message.
* Alias for format(...); Convenience function for adding i18n support.
* @tparam TArgs The format argument types.
* @param fmt The format string.
* @param args The format arguments.
* @return The formatted string.
*/
template <typename T, typename... TArgs>
void log(level lvl, boost::format& message, T arg, TArgs... args)
template<typename... TArgs>
inline std::string _(std::string const& fmt, TArgs&&... args)
{
message % arg;
log(lvl, message, std::forward<TArgs>(args)...);
return format(std::forward<decltype(fmt)>(fmt), std::forward<TArgs>(args)...);
}

/**
* Logs a given format message.
* @tparam TArgs The types of the arguments to format the message with.
* Log a message.
* @param lvl The logging level to log with.
* @param msg The message to log.
*/
LIBFACTER_EXPORT void log(level lvl, std::string const& msg);

/**
* Log a formatted message.
* @tparam TArgs The format argument types.
* @param lvl The logging level to log with.
* @param format The message format.
* @param args The remaining arguments to the message.
* @param fmt The format string.
* @param args The format arguments.
*/
template <typename... TArgs>
void log(level lvl, std::string const& format, TArgs... args)
inline void log(level lvl, std::string const& fmt, TArgs... args)
{
boost::format message(format);
log(lvl, message, std::forward<TArgs>(args)...);
log(std::forward<decltype(lvl)>(lvl), format(fmt, std::forward<TArgs>(args)...));
}

/**
Expand Down
2 changes: 1 addition & 1 deletion lib/inc/internal/util/agent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace facter { namespace util { namespace agent {
if (!fixed.empty()) {
return fixed;
}
LOG_WARNING("%1% not found at configured location %2%, using PATH instead", exe, FACTER_PATH);
LOG_WARNING("{1} not found at configured location {2}, using PATH instead", exe, FACTER_PATH);
#endif
return exe;
}
Expand Down
7 changes: 4 additions & 3 deletions lib/inc/internal/util/aix/odm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <memory>
#include <string>
#include <utility>
#include <leatherman/locale/locale.hpp>

namespace facter { namespace util { namespace aix {

Expand Down Expand Up @@ -66,7 +67,7 @@ namespace facter { namespace util { namespace aix {
char* msg;
int result = odm_err_msg(odmerrno, &msg);
if (result < 0) {
return "failed to retrieve ODM error message";
return leatherman::locale::format("failed to retrieve ODM error message");
} else {
return msg;
}
Expand Down Expand Up @@ -167,7 +168,7 @@ namespace facter { namespace util { namespace aix {
iterator(T* data, ptr owner) : _data(data), _owner(owner) {
if (_data) {
if (!_owner) {
throw std::logic_error("Tried to construct an iterator with valid data but no owner. Naughty naughty.");
throw std::logic_error(leatherman::locale::format("Tried to construct an iterator with valid data but no owner. Naughty naughty."));
}
_owner->_locked = true;
} else {
Expand Down Expand Up @@ -200,7 +201,7 @@ namespace facter { namespace util { namespace aix {
*/
iterator begin() {
if (_owner->_locked) {
throw std::logic_error("Cannot iterate over the same ODM class concurrently");
throw std::logic_error(leatherman::locale::format("Cannot iterate over the same ODM class concurrently"));
}
auto data = static_cast<T*>(odm_get_first(_owner->_class, const_cast<char*>(_query.c_str()), nullptr));
if ((intptr_t)data < 0) {
Expand Down
2 changes: 1 addition & 1 deletion lib/src/facts/aix/kernel_resolver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ namespace facter { namespace facts { namespace aix {
auto exec = execute("/usr/bin/oslevel", {"-s"}, 0, { execution_options::trim_output, execution_options::redirect_stderr_to_stdout, execution_options::merge_environment });

if (!exec.success) {
LOG_WARNING("oslevel failed: %1%: kernel facts are unavailable", exec.output);
LOG_WARNING("oslevel failed: {1}: kernel facts are unavailable", exec.output);
return result;
}

Expand Down
Loading

0 comments on commit dbfddf7

Please sign in to comment.