diff --git a/.gitignore b/.gitignore index a28d669..e8762be 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ -mason_packages \ No newline at end of file +mason_packages +cli +cli.dSYM +*.o \ No newline at end of file diff --git a/.mason b/.mason index 95ab9ca..6bfa09e 160000 --- a/.mason +++ b/.mason @@ -1 +1 @@ -Subproject commit 95ab9caff80d6327a13ed48f97c72ae4da4454bd +Subproject commit 6bfa09e828b496826d405b74a329c508a3307b8c diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..6cb1d4b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,45 @@ +language: generic + +env: + global: + - ASAN_OPTIONS=suppressions=asan_suppressions.txt + +matrix: + include: + - os: linux + sudo: false + env: CXX=g++-5 BUILDTYPE=Release + addons: + apt: + sources: [ 'ubuntu-toolchain-r-test' ] + packages: [ 'g++-5' ] + - os: linux + sudo: false + env: CXX=clang++-3.8 BUILDTYPE=Release + addons: + apt: + sources: [ 'ubuntu-toolchain-r-test' ] + packages: [ 'libstdc++6', 'libstdc++-5-dev' ] + - os: linux + sudo: false + env: CXX=clang++-3.8 BUILDTYPE=Debug CXXFLAGS="-fsanitize=address" LDFLAGS="-fsanitize=address" + addons: + apt: + sources: [ 'ubuntu-toolchain-r-test' ] + packages: [ 'libstdc++6', 'libstdc++-5-dev' ] + - os: osx + osx_image: xcode7.3 + env: BUILDTYPE=Release + +cache: apt + +install: + - | + if [[ ${CXX} =~ "clang" ]] && [[ $(uname -s) == "Linux" ]]; then + git clone --depth=1 https://github.com/mapbox/mason.git ./.mason + ./.mason/mason install clang 3.8.0 + export PATH=$(./.mason/mason prefix clang 3.8.0)/bin:${PATH} + which clang++ + fi +script: + - make test \ No newline at end of file diff --git a/Makefile b/Makefile index 5dedb0c..67a2bf5 100644 --- a/Makefile +++ b/Makefile @@ -1,21 +1,39 @@ CC := $(CC) CXX := $(CXX) CXXFLAGS := $(CXXFLAGS) -Iinclude -Imason_packages/.link/include -std=c++11 +LDFLAGS := $(LDFLAGS) -lboost_program_options -lboost_system + +MASON ?= .mason/mason +MASON_HOME := ./mason_packages/.link + RELEASE_FLAGS := -O3 -DNDEBUG WARNING_FLAGS := -Wall -Wextra -Werror -Wsign-compare -Wfloat-equal -Wfloat-conversion -Wshadow -Wno-unsequenced DEBUG_FLAGS := -g -O0 -DDEBUG -fno-inline-functions -fno-omit-frame-pointer -MASON ?= .mason/mason -default: test +ifeq ($(BUILDTYPE),Release) + FINAL_FLAGS := -g $(WARNING_FLAGS) $(RELEASE_FLAGS) +else + FINAL_FLAGS := -g $(WARNING_FLAGS) $(DEBUG_FLAGS) +endif -clean: - rm -rf mason_packages +default: cli + +cli: mason_packages clean + $(CXX) cli.cpp -o cli -isystem$(MASON_HOME)/include $(CXXFLAGS) $(FINAL_FLAGS) $(LDFLAGS) + +test: cli + ./tests/cli.test.sh $(MASON): git submodule update --init mason_packages: $(MASON) - $(MASON) install hpp_skel 0.0.1 + $(MASON) install hpp_skel 1.0.0 && $(MASON) link hpp_skel 1.0.0 + $(MASON) install boost_libprogram_options 1.61.0 && $(MASON) link boost_libprogram_options 1.61.0 + +clean: + rm -f cli + rm -f *.o -cli: mason_packages - # $(CXX) cli.cpp -o cli -isystem$(MASON_HOME)/include -L$(MASON_HOME)/lib $(CXXFLAGS) $(FINAL_FLAGS) $(LDFLAGS); \ No newline at end of file +clean-mason: + rm -rf mason_packages \ No newline at end of file diff --git a/cli.cpp b/cli.cpp index e872413..75241fd 100644 --- a/cli.cpp +++ b/cli.cpp @@ -1,12 +1,50 @@ -#include +#include +#include #include #include -using namespace hello_world; +#define VERSION "v0.0.1\n" -int main() { - std::string value = exclaim("hello"); - std::clog << value; - return 0; +using namespace boost::program_options; + +int main(int argc, char** argv) { + try { + options_description desc("\nusage: cli "); + + desc.add_options() + ("help,h", "show help") + ("version,v", "show version number") + ("phrase,p", value(), "Input phrase"); + + positional_options_description p; + p.add("phrase", 1); + variables_map vm; + + auto parser = command_line_parser(argc, argv).options(desc).positional(p); + store(parser.run(), vm); + + if (vm.count("help")) { + std::cout << desc; + } else if (vm.count("version")) { + std::cout << VERSION; + } else { + std::string phrase; + if (vm.count("phrase")) { + phrase = vm["phrase"].as(); + } else { + std::cout << "Error: you must pass in a phrase to be exclaimed." << "\n"; + return 1; + } + + // use hello_world::exclaim + std::string output(hello_world::exclaim(phrase)); + std::cout << output << "\n"; + + return 0; + } + } catch (std::exception const& ex) { + std::cout << "error: " << ex.what() << "\n"; + return -1; + } } \ No newline at end of file diff --git a/tests/cli.test.sh b/tests/cli.test.sh new file mode 100755 index 0000000..308190a --- /dev/null +++ b/tests/cli.test.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +# run cli command directly in bash, capture the result and test it +PWD=$(pwd) +RESULT=$($PWD/cli waka) +if [ $RESULT == "!waka!" ] +then + echo "Success." + exit 0 +else + echo "Test failed: cli output is not as expected." + echo "EXPECTED: !waka! - ACTUAL: $RESULT" + exit -1 +fi \ No newline at end of file