diff --git a/.travis.yml b/.travis.yml index ad17693a9..147cd13fe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,13 +3,17 @@ language: cpp cache: pip: true directories: + - $HOME/DF-travis - $HOME/lua53 addons: apt: packages: &default_packages + - libsdl-image1.2-dev + - libsdl-ttf2.0-dev + - libsdl1.2-dev - libxml-libxml-perl - libxml-libxslt-perl - - zlib1g-dev:i386 + - zlib1g-dev matrix: include: - env: GCC_VERSION=4.8 @@ -19,11 +23,15 @@ matrix: - ubuntu-toolchain-r-test packages: - *default_packages - - gcc-4.8-multilib - - g++-4.8-multilib + - gcc-4.8 + - g++-4.8 before_install: +- export DF_VERSION=$(sh travis/get-df-version.sh) +- export DF_FOLDER="$HOME/DF-travis/$DF_VERSION" - pip install --user "sphinx==1.4" "requests[security]" - sh travis/build-lua.sh +- sh travis/download-df.sh +- echo "export DFHACK_HEADLESS=1" >> "$HOME/.dfhackrc" script: - export PATH="$PATH:$HOME/lua53/bin" - git tag tmp-travis-build @@ -37,12 +45,16 @@ script: - python travis/script-syntax.py --ext=rb --cmd="ruby -c" - mkdir build-travis - cd build-travis -- cmake .. -DCMAKE_C_COMPILER=gcc-$GCC_VERSION -DCMAKE_CXX_COMPILER=g++-$GCC_VERSION -DBUILD_DOCS:BOOL=ON -- make -j3 +- cmake .. -DCMAKE_C_COMPILER=gcc-$GCC_VERSION -DCMAKE_CXX_COMPILER=g++-$GCC_VERSION -DDFHACK_BUILD_ARCH=64 -DBUILD_DOCS:BOOL=ON -DCMAKE_INSTALL_PREFIX="$DF_FOLDER" +- make -j3 install +- mv "$DF_FOLDER"/dfhack.init-example "$DF_FOLDER"/dfhack.init +- cd .. +- cp travis/dfhack_travis.init "$DF_FOLDER"/ +- python travis/run-tests.py "$DF_FOLDER" notifications: email: false - irc: - channels: - - "chat.freenode.net#dfhack" - on_success: change - on_failure: always + # irc: + # channels: + # - "chat.freenode.net#dfhack" + # on_success: change + # on_failure: always diff --git a/library/Core.cpp b/library/Core.cpp index 5173a3ad9..58b3f85f5 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -81,6 +81,10 @@ using namespace DFHack; #include "SDL_events.h" +#ifdef LINUX_BUILD +#include +#endif + using namespace tthread; using namespace df::enums; using df::global::init; @@ -1638,7 +1642,24 @@ bool Core::Init() cerr << "Initializing Console.\n"; // init the console. bool is_text_mode = (init && init->display.flag.is_set(init_display_flags::TEXT)); - if (is_text_mode || getenv("DFHACK_DISABLE_CONSOLE")) + bool is_headless = bool(getenv("DFHACK_HEADLESS")); + if (is_headless) + { +#ifdef LINUX_BUILD + auto endwin = (int(*)(void))dlsym(RTLD_DEFAULT, "endwin"); + if (endwin) + { + endwin(); + } + else + { + cerr << "endwin(): bind failed" << endl; + } +#else + cerr << "Headless mode not supported on Windows" << endl; +#endif + } + if ((is_text_mode && !is_headless) || getenv("DFHACK_DISABLE_CONSOLE")) { con.init(true); cerr << "Console is not available. Use dfhack-run to send commands.\n"; @@ -1718,7 +1739,7 @@ bool Core::Init() HotkeyMutex = new mutex(); HotkeyCond = new condition_variable(); - if (!is_text_mode) + if (!is_text_mode || is_headless) { cerr << "Starting IO thread.\n"; // create IO thread diff --git a/library/Hooks-linux.cpp b/library/Hooks-linux.cpp index b0bf5a781..8291bf899 100644 --- a/library/Hooks-linux.cpp +++ b/library/Hooks-linux.cpp @@ -88,6 +88,10 @@ DFhackCExport int SDL_PollEvent(SDL::Event* event) struct WINDOW; DFhackCExport int wgetch(WINDOW *win) { + if (getenv("DFHACK_HEADLESS")) + { + return 0; + } static int (*_wgetch)(WINDOW * win) = (int (*)( WINDOW * )) dlsym(RTLD_NEXT, "wgetch"); if(!_wgetch) { diff --git a/test/main.lua b/test/main.lua new file mode 100644 index 000000000..0085a9711 --- /dev/null +++ b/test/main.lua @@ -0,0 +1,10 @@ +function set_test_stage(stage) + local f = io.open('test_stage.txt', 'w') + f:write(stage) + f:close() +end + +print('running tests') + +set_test_stage('done') +dfhack.run_command('die') diff --git a/travis/dfhack_travis.init b/travis/dfhack_travis.init new file mode 100644 index 000000000..d9bc3e5ba --- /dev/null +++ b/travis/dfhack_travis.init @@ -0,0 +1,2 @@ +:lua dfhack.internal.addScriptPath(os.getenv('TRAVIS_BUILD_DIR')) +test/main diff --git a/travis/download-df.sh b/travis/download-df.sh new file mode 100755 index 000000000..20dc3dbd4 --- /dev/null +++ b/travis/download-df.sh @@ -0,0 +1,40 @@ +#!/bin/sh + +tardest="df.tar.bz2" + +which md5sum && alias md5=md5sum +selfmd5=$(openssl md5 < "$0") +echo $selfmd5 + +cd "$(dirname "$0")" +echo "DF_VERSION: $DF_VERSION" +echo "DF_FOLDER: $DF_FOLDER" +mkdir -p "$DF_FOLDER" +cd "$DF_FOLDER" + +if [ -f receipt ]; then + if [ "$selfmd5" != "$(cat receipt)" ]; then + echo "download-df.sh changed; removing DF" + else + echo "Already downloaded $DF_VERSION" + exit 0 + fi +fi + +rm -rif "$tardest" df_linux + +minor=$(echo "$DF_VERSION" | cut -d. -f2) +patch=$(echo "$DF_VERSION" | cut -d. -f3) +url="http://www.bay12games.com/dwarves/df_${minor}_${patch}_linux.tar.bz2" + +echo Downloading +wget "$url" -O "$tardest" +echo Extracting +tar xf "$tardest" --strip-components=1 +echo Changing settings +echo '' >> "$DF_FOLDER/data/init/init.txt" +echo '[PRINT_MODE:TEXT]' >> "$DF_FOLDER/data/init/init.txt" +echo '[SOUND:NO]' >> "$DF_FOLDER/data/init/init.txt" +echo Done + +echo "$selfmd5" > receipt diff --git a/travis/get-df-version.sh b/travis/get-df-version.sh new file mode 100755 index 000000000..13d317d2e --- /dev/null +++ b/travis/get-df-version.sh @@ -0,0 +1,4 @@ +#!/bin/sh +cd "$(dirname "$0")" +cd .. +grep DF_VERSION CMakeLists.txt | perl -ne 'print "$&\n" if /[\d\.]+/' diff --git a/travis/run-tests.py b/travis/run-tests.py new file mode 100644 index 000000000..a8265088c --- /dev/null +++ b/travis/run-tests.py @@ -0,0 +1,30 @@ +import os, subprocess, sys + +MAX_TRIES = 5 + +dfhack = 'Dwarf Fortress.exe' if sys.platform == 'win32' else './dfhack' +test_stage = 'test_stage.txt' + +def get_test_stage(): + if os.path.isfile(test_stage): + return open(test_stage).read().strip() + return '0' + +os.chdir(sys.argv[1]) +if os.path.exists(test_stage): + os.remove(test_stage) + +tries = 0 +while True: + tries += 1 + stage = get_test_stage() + print('Run #%i: stage=%s' % (tries, get_test_stage())) + if stage == 'done': + print('Done!') + os.remove(test_stage) + sys.exit(0) + if tries > MAX_TRIES: + print('Too many tries - aborting') + sys.exit(1) + + os.system(dfhack)