Commit 4e0e04a9 authored by Paul Asmuth's avatar Paul Asmuth
Browse files

simple cli :)

parent b33f7cd2
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -57,6 +57,10 @@ set(CMAKE_CXX_FLAGS "-std=c++0x -stdlib=libc++")
add_definitions("-Wno-predefined-identifier-outside-function")
# add_library(fnordmetric SHARED ${FNORDMETRIC_SOURCES})

add_executable(fnordmetric
    ${FNORDMETRIC_CLI_SOURCES}
    stage/src/fnordmetric/main.cc)

add_executable(tests/test-query
    ${FNORDMETRIC_QUERY_SOURCES}
    stage/src/fnordmetric/query/query_test.cc)
+92 −13
Original line number Diff line number Diff line
@@ -16,10 +16,90 @@
namespace fnordmetric {
namespace cli {

void CLI::execute(const cli::FlagParser& flag_parser) {
FlagParser CLI::getDefaultFlagParser() {
  FlagParser flag_parser;

  flag_parser.defineFlag(
      "format",
      FlagParser::T_STRING,
      false,
      "f",
      "human",
      "The output format (svg,csv,human)",
      "<format>");

  flag_parser.defineFlag(
      "output",
      FlagParser::T_STRING,
      false,
      "o",
      NULL,
      "Write output to a file",
      "<format>");

  flag_parser.defineFlag(
      "verbose",
      FlagParser::T_SWITCH,
      false,
      NULL,
      NULL,
      "Be verbose");

  flag_parser.defineFlag(
      "help",
      FlagParser::T_SWITCH,
      false,
      "h",
      NULL,
      "You are reading it...");

  return flag_parser;
}

int CLI::executeSafely(
      const std::vector<std::string>& argv,
      util::OutputStream* error_stream) {
  bool verbose = true;
  auto flag_parser = getDefaultFlagParser();

  try {
    flag_parser.parseArgv(argv);
    verbose = flag_parser.isSet("verbose");
    execute(flag_parser, error_stream);
  } catch (util::RuntimeException e) {
    if (e.getTypeName() == "UsageError") {
      flag_parser.printUsage(error_stream);
      return 1;
    }

    error_stream->printf("fatal error: %s\n", e.getMessage().c_str());

    if (verbose) {
      e.debugPrint();
    }

    return 1;
  }

  return 0;
}

void CLI::execute(
      const std::vector<std::string>& argv,
      util::OutputStream* error_stream) {
  /* parse flags */
  auto flag_parser = getDefaultFlagParser();
  flag_parser.parseArgv(argv);
  bool verbose = flag_parser.isSet("verbose");
  auto err = util::OutputStream::getStderr();
  const auto& args = flag_parser.getArgv();
  execute(flag_parser, error_stream);
}

void CLI::execute(
      const FlagParser& flag_parser,
      util::OutputStream* error_stream) {
  const auto& args = flag_parser.getArgv();
  bool verbose = flag_parser.isSet("verbose");

  /* web / cgi mode */

@@ -27,22 +107,21 @@ void CLI::execute(const cli::FlagParser& flag_parser) {

  /* open input stream */
  std::unique_ptr<util::InputStream> input;
  switch (args.size()) {
    case 0:
  if (args.size() == 1) {
    if (args[0] == "-") {
      if (verbose) {
        err->printf("[INFO] input from stdin %s\n");
        error_stream->printf("[INFO] input from stdin %s\n");
      }

      input = std::move(util::InputStream::getStdin());
      break;
    case 1:
    } else {
      if (verbose) {
        err->printf("[INFO] input file: %s\n", args[0].c_str());
        error_stream->printf("[INFO] input file: %s\n", args[0].c_str());
      }

      input = std::move(util::FileInputStream::openFile(args[0]));
      break;
    default:
    }
  } else {
    RAISE(UsageError);
  }

@@ -52,13 +131,13 @@ void CLI::execute(const cli::FlagParser& flag_parser) {
    auto output_file = flag_parser.getString("output");

    if (verbose) {
      err->printf("[INFO] output file: %s\n", output_file.c_str());
      error_stream->printf("[INFO] output file: %s\n", output_file.c_str());
    }

    output = std::move(util::FileOutputStream::openFile(output_file));
  } else {
    if (verbose) {
      err->printf("[INFO] output to stdout\n");
      error_stream->printf("[INFO] output to stdout\n");
    }
    output = std::move(util::OutputStream::getStdout());
  }
+24 −6
Original line number Diff line number Diff line
@@ -9,6 +9,9 @@
#include <fnordmetric/util/runtimeexception.h>

namespace fnordmetric {
namespace util {
class OutputStream;
}
namespace cli {
class FlagParser;

@@ -18,14 +21,29 @@ public:
    UsageError() : RuntimeException("usage error") {}
  };

  static FlagParser getDefaultFlagParser();

  /**
   * Execute a command line
   *
   * May throw an exception!
   * Execute a command line. Should not throw an exception!
   */
  static void execute(const cli::FlagParser& flag_parser);
}
;
  static int executeSafely(
      const std::vector<std::string>& argv,
      util::OutputStream* error_stream);

  /**
   * Execute a command line. May throw an exception!
   */
  static void execute(
      const std::vector<std::string>& argv,
      util::OutputStream* error_stream);

  /**
   * Execute a command line.  May throw an exception!
   */
  static void execute(
      const FlagParser& flag_parser,
      util::OutputStream* error_stream);
};

}
}
+4 −29
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
#include <fnordmetric/util/unittest.h>
#include <fnordmetric/cli/cli.h>
#include <fnordmetric/cli/flagparser.h>
#include <fnordmetric/util/outputstream.h>

using namespace fnordmetric::cli;

@@ -23,36 +24,10 @@ static fnordmetric::util::UnitTest::TestCase __test_simple_sql_to_svg_(
    "-o", "build/tests/tmp/CLITest_TestSimpleSQLToSVG_out.svg.html"
  };

  FlagParser flag_parser;

  flag_parser.defineFlag(
      "verbose",
      FlagParser::T_SWITCH,
      false,
      "v",
      NULL,
      "Be verbose");

  flag_parser.defineFlag(
      "format",
      FlagParser::T_STRING,
      false,
      "f",
      "human",
      "The output format (svg,csv,human)",
      "<output_format>");

  flag_parser.defineFlag(
      "output",
      FlagParser::T_STRING,
      false,
      "o",
      NULL,
      "The output format (svg,csv,human)",
      "<output_format>");

  auto flag_parser = CLI::getDefaultFlagParser();
  auto error_stream = fnordmetric::util::OutputStream::getStderr();
  flag_parser.parseArgv(args);
  CLI::execute(flag_parser);
  CLI::execute(flag_parser, error_stream.get());

  EXPECT_FILES_EQ(
    "test/fixtures/CLITest_TestSimpleSQLToSVG_out.svg.html",
+45 −0
Original line number Diff line number Diff line
#include <string>
#include <vector>
#include <fnordmetric/cli/flagparser.h>
#include <fnordmetric/util/outputstream.h>
#include <fnordmetric/util/runtimeexception.h>

namespace fnordmetric {
@@ -125,5 +126,49 @@ const std::vector<std::string>& FlagParser::getArgv() const {
  return argv_;
}

void FlagParser::printUsage(util::OutputStream* target) const {
  target->printf("usage: fnordmetric [options] [file.sql]\n");

  target->printf("\noptions:\n");
  for (const auto& flag : flags_) {
    if (flag.shortopt == nullptr) {
      target->printf("    --%-16.16s", flag.longopt);
    } else {
      target->printf("    -%s, --%-12.12s", flag.shortopt, flag.longopt);
    }

    const char* placeholder = nullptr;
    if (flag.placeholder == nullptr) {
      switch (flag.type) {
        case T_STRING:
          placeholder = "<string>";
          break;
        case T_INTEGER:
          placeholder = "<int>";
          break;
        case T_FLOAT:
          placeholder = "<float>";
          break;
        case T_SWITCH:
          placeholder = "";
          break;
      }
    } else {
      placeholder = flag.placeholder;
    }
    target->printf("%-12.12s", placeholder);

    if (flag.description != nullptr) {
      target->printf("%s\n", flag.description);
    } else {
      target->printf("\n");
    }
  }

  target->printf("\nexamples:\n");
  target->printf("    $ fnordmeric -f svg -o out.svg myquery.sql\n");
  target->printf("    $ fnordmeric -f svg - < myquery.sql > out.svg\n");
}

}
}
Loading