From 74d147a0bef5fd3b90307269c295b54ebdcbd861 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 23 Aug 2014 03:55:37 +0400 Subject: [PATCH 01/12] Use `open` to open file descriptors in place of `file` Reason: there is no `file()` in Python 3. Fix was originally presented by @kovidgoyal in [3deb69][1], but I cannot cherry-pick this commit, because its commit message is highly undescriptive. Fixes #1008 [1]: https://github.com/kovidgoyal/powerline-daemon/commit/3deb6988c8992d92ef43d9f03c7a725ac9836c20 --- scripts/powerline-daemon | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/powerline-daemon b/scripts/powerline-daemon index 20794575..4a8ffb9b 100755 --- a/scripts/powerline-daemon +++ b/scripts/powerline-daemon @@ -274,9 +274,9 @@ def daemonize(stdin=os.devnull, stdout=os.devnull, stderr=os.devnull): sys.exit(1) # Redirect standard file descriptors. - si = file(stdin, 'r') - so = file(stdout, 'a+') - se = file(stderr, 'a+', 0) + si = open(stdin, 'rb') + so = open(stdout, 'a+b') + se = open(stderr, 'a+b', 0) os.dup2(si.fileno(), sys.stdin.fileno()) os.dup2(so.fileno(), sys.stdout.fileno()) os.dup2(se.fileno(), sys.stderr.fileno()) From dc763969124bc6ef2d59cfef0537b7ed9e7f23b7 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 23 Aug 2014 04:10:47 +0400 Subject: [PATCH 02/12] Solve encoding issues in powerline python client --- client/powerline.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/client/powerline.py b/client/powerline.py index 5cec13e8..6b76e804 100755 --- a/client/powerline.py +++ b/client/powerline.py @@ -8,6 +8,7 @@ import socket import os import errno + if len(sys.argv) < 2: print('Must provide at least one argument.', file=sys.stderr) raise SystemExit(1) @@ -42,22 +43,23 @@ fenc = sys.getfilesystemencoding() or 'utf-8' if fenc == 'ascii': fenc = 'utf-8' -args = [bytes('%x' % (len(sys.argv) - 1))] -args.extend((x.encode(fenc) if isinstance(x, type('')) else x for x in sys.argv[1:])) +tobytes = lambda s: s if isinstance(s, bytes) else s.encode(fenc) + +args = [tobytes('%x' % (len(sys.argv) - 1))] +args.extend((tobytes(s) for s in sys.argv[1:])) + try: cwd = os.getcwd() except EnvironmentError: pass else: - if isinstance(cwd, type('')): + if not isinstance(cwd, bytes): cwd = cwd.encode(fenc) args.append(cwd) -env = (k + b'=' + v for k, v in os.environ.items()) -env = (x if isinstance(x, bytes) else x.encode(fenc, 'replace') for x in env) -args.extend(env) +args.extend((tobytes(k) + b'=' + tobytes(v) for k, v in os.environ.items())) EOF = b'\0\0' @@ -75,4 +77,7 @@ while True: sock.close() -sys.stdout.write(b''.join(received)) +if sys.version_info < (3,): + sys.stdout.write(b''.join(received)) +else: + sys.stdout.buffer.write(b''.join(received)) From 8e77262f2d1b5d75a1242e99261f77012be1bdae Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 23 Aug 2014 04:19:54 +0400 Subject: [PATCH 03/12] Perform shell word splitting in zsh bindings This makes POWERLINE_COMMAND be consistent across various bindings. --- docs/source/configuration/local.rst | 8 +++----- powerline/bindings/zsh/powerline.zsh | 12 ++++++------ 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/docs/source/configuration/local.rst b/docs/source/configuration/local.rst index 13902514..316e83c6 100644 --- a/docs/source/configuration/local.rst +++ b/docs/source/configuration/local.rst @@ -122,11 +122,9 @@ powerline into different directory. .. note:: ``$POWERLINE_COMMAND`` appears in shell scripts without quotes thus you can - specify additional parameters in bash. In zsh you will have to make - ``$POWERLINE_COMMAND`` an array parameter to achieve the same result. In - tmux it is passed to ``eval`` and depends on the shell used. - POSIX-compatible shells, zsh, bash and fish will split this variable in this - case. + specify additional parameters in bash. In tmux it is passed to ``eval`` and + depends on the shell used. POSIX-compatible shells, zsh, bash and fish will + split this variable in this case. If you want to disable prompt in shell, but still have tmux support or if you want to disable tmux support you can use variables diff --git a/powerline/bindings/zsh/powerline.zsh b/powerline/bindings/zsh/powerline.zsh index b75f138d..42eafe45 100644 --- a/powerline/bindings/zsh/powerline.zsh +++ b/powerline/bindings/zsh/powerline.zsh @@ -131,7 +131,7 @@ _powerline_setup_prompt() { } else if test -z "${POWERLINE_COMMAND}" ; then - POWERLINE_COMMAND=( "$($POWERLINE_CONFIG shell command)" ) + POWERLINE_COMMAND="$($POWERLINE_CONFIG shell command)" fi local add_args='-r .zsh' @@ -145,11 +145,11 @@ _powerline_setup_prompt() { local add_args_2=$add_args$new_args_2 add_args+=' --width=$(( ${COLUMNS:-$(_powerline_columns_fallback)} - 1 ))' local add_args_r2=$add_args$new_args_2 - PS1='$($POWERLINE_COMMAND shell aboveleft '$add_args')' - RPS1='$($POWERLINE_COMMAND shell right '$add_args')' - PS2='$($POWERLINE_COMMAND shell left '$add_args_2')' - RPS2='$($POWERLINE_COMMAND shell right '$add_args_r2')' - PS3='$($POWERLINE_COMMAND shell left '$add_args_3')' + PS1='$($=POWERLINE_COMMAND shell aboveleft '$add_args')' + RPS1='$($=POWERLINE_COMMAND shell right '$add_args')' + PS2='$($=POWERLINE_COMMAND shell left '$add_args_2')' + RPS2='$($=POWERLINE_COMMAND shell right '$add_args_r2')' + PS3='$($=POWERLINE_COMMAND shell left '$add_args_3')' fi } From 03c22e94a7833c352be89c916fcacd6cb565e682 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 23 Aug 2014 04:30:22 +0400 Subject: [PATCH 04/12] Make tcsh check whether some variables are defined or empty Makes it consistent with other shells --- docs/source/configuration/local.rst | 6 ------ powerline/bindings/tcsh/powerline.tcsh | 12 ++++++++++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/docs/source/configuration/local.rst b/docs/source/configuration/local.rst index 316e83c6..c66b5c78 100644 --- a/docs/source/configuration/local.rst +++ b/docs/source/configuration/local.rst @@ -145,9 +145,3 @@ tcsh you should set ``$POWERLINE_NO_TCSH_ABOVE`` or If you do not want to see additional space which is added to the right prompt in fish in order to support multiline prompt you should set ``$POWERLINE_NO_FISH_ABOVE`` or ``$POWERLINE_NO_SHELL_ABOVE`` variables. - -.. note:: - - Most supported shells’ configuration scripts check for ``$POWERLINE_CONFIG`` - and ``$POWERLINE_COMMAND`` configuration variables being empty. But tcsh - configuration script checks for variables being *defined*, not empty. diff --git a/powerline/bindings/tcsh/powerline.tcsh b/powerline/bindings/tcsh/powerline.tcsh index ac93341b..fafdb39b 100644 --- a/powerline/bindings/tcsh/powerline.tcsh +++ b/powerline/bindings/tcsh/powerline.tcsh @@ -11,6 +11,14 @@ if ! $?POWERLINE_CONFIG then else set POWERLINE_CONFIG="$POWERLINE_SOURCED[2]:h:h:h:h/scripts/powerline-config" endif +else + if "$POWERLINE_CONFIG" == "" then + if ( { which powerline-config > /dev/null } ) then + set POWERLINE_CONFIG="powerline-config" + else + set POWERLINE_CONFIG="$POWERLINE_SOURCED[2]:h:h:h:h/scripts/powerline-config" + endif + endif endif if ( { $POWERLINE_CONFIG shell --shell=tcsh uses tmux } ) then alias _powerline_tmux_set_pwd 'if ( $?TMUX && { tmux refresh -S >&/dev/null } ) tmux setenv -g TMUX_PWD_`tmux display -p "#D" | tr -d %` $PWD:q ; if ( $?TMUX ) tmux refresh -S >&/dev/null' @@ -19,6 +27,10 @@ endif if ( { $POWERLINE_CONFIG shell --shell=tcsh uses prompt } ) then if ! $?POWERLINE_COMMAND then set POWERLINE_COMMAND="`$POWERLINE_CONFIG:q shell command`" + else + if "$POWERLINE_COMMAND" == "" then + set POWERLINE_COMMAND="`$POWERLINE_CONFIG:q shell command`" + endif endif if ( $?POWERLINE_NO_TCSH_ABOVE || $?POWERLINE_NO_SHELL_ABOVE ) then From b9360a083aa3c0dcb40287985256648226df9dfa Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 23 Aug 2014 03:28:51 +0400 Subject: [PATCH 05/12] Make tests test powerline daemon with valid python and all clients --- tests/install.sh | 2 +- tests/test_shells/postproc.py | 7 +- tests/test_shells/screenrc | 2 +- tests/test_shells/test.sh | 179 ++++++++++++++++++++++------------ 4 files changed, 123 insertions(+), 67 deletions(-) diff --git a/tests/install.sh b/tests/install.sh index fcfd0b73..e9e243b3 100755 --- a/tests/install.sh +++ b/tests/install.sh @@ -22,7 +22,7 @@ else pip install ipython fi fi -sudo apt-get install -qq screen zsh tcsh mksh busybox +sudo apt-get install -qq screen zsh tcsh mksh busybox socat # Travis has too outdated fish. It cannot be used for tests. # sudo apt-get install fish true diff --git a/tests/test_shells/postproc.py b/tests/test_shells/postproc.py index 6866dfc1..d86fe6fc 100755 --- a/tests/test_shells/postproc.py +++ b/tests/test_shells/postproc.py @@ -9,9 +9,10 @@ import codecs test_type = sys.argv[1] -shell = sys.argv[2] -fname = os.path.join('tests', 'shell', shell + '.' + test_type + '.full.log') -new_fname = os.path.join('tests', 'shell', shell + '.' + test_type + '.log') +test_client = sys.argv[2] +shell = sys.argv[3] +fname = os.path.join('tests', 'shell', '.'.join((shell, test_type, test_client, 'full.log'))) +new_fname = os.path.join('tests', 'shell', '.'.join((shell, test_type, test_client, 'log'))) pid_fname = os.path.join('tests', 'shell', '3rd', 'pid') diff --git a/tests/test_shells/screenrc b/tests/test_shells/screenrc index 7c9674e5..3ba7ba7f 100644 --- a/tests/test_shells/screenrc +++ b/tests/test_shells/screenrc @@ -1,3 +1,3 @@ width 1024 height 1 -logfile "tests/shell/${SH}.${TEST_TYPE}.full.log" +logfile "tests/shell/${SH}.${TEST_TYPE}.${TEST_CLIENT}.full.log" diff --git a/tests/test_shells/test.sh b/tests/test_shells/test.sh index b9b46529..40990e81 100755 --- a/tests/test_shells/test.sh +++ b/tests/test_shells/test.sh @@ -1,23 +1,46 @@ #!/bin/bash +: ${PYTHON:=python} FAILED=0 ONLY_SHELL="$1" +ONLY_TEST_TYPE="$2" +COMMAND_PATTERN="$3" + +export PYTHON + +if test "x$ONLY_SHELL" = "x--help" ; then +cat << EOF +Usage: + $0 [[[ONLY_SHELL | ""] (ONLY_TEST_TYPE | "")] (COMMAND_PATTERN | "")] + +ONLY_SHELL: execute only tests for given shell +ONLY_TEST_TYPE: execute only "daemon" or "nodaemon" tests +COMMAND_PATTERN: use only commands that match given pattern for testing +EOF +fi check_screen_log() { TEST_TYPE="$1" - SH="$2" + TEST_CLIENT="$2" + SH="$3" if test -e tests/test_shells/${SH}.${TEST_TYPE}.ok ; then - diff -a -u tests/test_shells/${SH}.${TEST_TYPE}.ok tests/shell/${SH}.${TEST_TYPE}.log + diff -a -u tests/test_shells/${SH}.${TEST_TYPE}.ok tests/shell/${SH}.${TEST_TYPE}.${TEST_CLIENT}.log return $? elif test -e tests/test_shells/${SH}.ok ; then - diff -a -u tests/test_shells/${SH}.ok tests/shell/${SH}.${TEST_TYPE}.log + diff -a -u tests/test_shells/${SH}.ok tests/shell/${SH}.${TEST_TYPE}.${TEST_CLIENT}.log return $? else - cat tests/shell/${SH}.${TEST_TYPE}.log + cat tests/shell/${SH}.${TEST_TYPE}.${TEST_CLIENT}.log return 1 fi } run() { + TEST_TYPE="$1" + shift + TEST_CLIENT="$1" + shift + SH="$1" + shift local local_path="$PWD/tests/shell/path:$PWD/scripts" if test "x$SH" = "xfish" ; then local_path="${local_path}:/usr/bin:/bin" @@ -33,6 +56,7 @@ run() { COLUMNS="${COLUMNS}" \ LINES="${LINES}" \ TEST_TYPE="${TEST_TYPE}" \ + TEST_CLIENT="${TEST_CLIENT}" \ SH="${SH}" \ DIR1="${DIR1}" \ DIR2="${DIR2}" \ @@ -40,27 +64,22 @@ run() { IPYTHONDIR="$PWD/tests/shell/ipython_home" \ POWERLINE_SHELL_CONTINUATION=$additional_prompts \ POWERLINE_SHELL_SELECT=$additional_prompts \ + POWERLINE_COMMAND="${POWERLINE_COMMAND}" \ "$@" } run_test() { TEST_TYPE="$1" shift + TEST_CLIENT="$1" + shift SH="$1" SESNAME="powerline-shell-test-${SH}-$$" ARGS=( "$@" ) - test "x$ONLY_SHELL" = "x" || test "x$ONLY_SHELL" = "x$SH" || return 0 - - if ! which "${SH}" ; then - return 0 - fi - - export TEST_TYPE - export SH - - run screen -L -c tests/test_shells/screenrc -d -m -S "$SESNAME" \ - env LANG=en_US.UTF-8 BINDFILE="$BINDFILE" "${ARGS[@]}" + run "${TEST_TYPE}" "${TEST_CLIENT}" "${SH}" \ + screen -L -c tests/test_shells/screenrc -d -m -S "$SESNAME" \ + env LANG=en_US.UTF-8 BINDFILE="$BINDFILE" "${ARGS[@]}" while ! screen -S "$SESNAME" -X readreg a tests/test_shells/input.$SH ; do sleep 0.1s done @@ -88,23 +107,27 @@ run_test() { while screen -S "$SESNAME" -X blankerprg "" > /dev/null ; do sleep 0.1s done - ./tests/test_shells/postproc.py ${TEST_TYPE} ${SH} + ./tests/test_shells/postproc.py ${TEST_TYPE} ${TEST_CLIENT} ${SH} rm -f tests/shell/3rd/pid - if ! check_screen_log ${TEST_TYPE} ${SH} ; then - echo '____________________________________________________________' - # Repeat the diff to make it better viewable in travis output - echo "Diff (cat -v):" - echo '============================================================' - check_screen_log ${TEST_TYPE} ${SH} | cat -v + if ! check_screen_log ${TEST_TYPE} ${TEST_CLIENT} ${SH} ; then echo '____________________________________________________________' + if test "x$POWERLINE_TEST_NO_CAT_V" != "x1" ; then + # Repeat the diff to make it better viewable in travis output + echo "Diff (cat -v):" + echo '============================================================' + check_screen_log ${TEST_TYPE} ${TEST_CLIENT} ${SH} | cat -v + echo '____________________________________________________________' + fi echo "Failed ${SH}. Full output:" echo '============================================================' - cat tests/shell/${SH}.${TEST_TYPE}.full.log - echo '____________________________________________________________' - echo "Full output (cat -v):" - echo '============================================================' - cat -v tests/shell/${SH}.${TEST_TYPE}.full.log + cat tests/shell/${SH}.${TEST_TYPE}.${TEST_CLIENT}.full.log echo '____________________________________________________________' + if test "x$POWERLINE_TEST_NO_CAT_V" != "x1" ; then + echo "Full output (cat -v):" + echo '============================================================' + cat -v tests/shell/${SH}.${TEST_TYPE}.${TEST_CLIENT}.full.log + echo '____________________________________________________________' + fi case ${SH} in *ksh) ${SH} -c 'echo ${KSH_VERSION}' @@ -146,7 +169,7 @@ mkdir tests/shell/fish_home cp -r tests/test_shells/ipython_home tests/shell mkdir tests/shell/path -ln -s "$(which "${PYTHON:-python}")" tests/shell/path/python +ln -s "$(which "${PYTHON}")" tests/shell/path/python ln -s "$(which screen)" tests/shell/path ln -s "$(which env)" tests/shell/path ln -s "$(which sleep)" tests/shell/path @@ -168,6 +191,9 @@ ln -s "$(which sed)" tests/shell/path ln -s "$(which rm)" tests/shell/path ln -s ../../test_shells/bgscript.sh tests/shell/path ln -s ../../test_shells/waitpid.sh tests/shell/path +if which socat ; then + ln -s "$(which socat)" tests/shell/path +fi for pexe in powerline powerline-config ; do if test -e scripts/$pexe ; then ln -s "$PWD/scripts/$pexe" tests/shell/path @@ -194,40 +220,66 @@ if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || te scripts/powerline-config shell command for TEST_TYPE in "daemon" "nodaemon" ; do - if test $TEST_TYPE == daemon ; then - sh -c 'echo $$ > tests/shell/daemon_pid; ./scripts/powerline-daemon -f &>tests/shell/daemon_log' & + if test $TEST_TYPE = daemon ; then + sh -c 'echo $$ > tests/shell/daemon_pid; $PYTHON ./scripts/powerline-daemon -f &>tests/shell/daemon_log' & fi - if ! run_test $TEST_TYPE bash --norc --noprofile -i ; then - FAILED=1 + if test "x$ONLY_TEST_TYPE" != "x" && test "x$ONLY_TEST_TYPE" != "x$TEST_TYPE" ; then + continue fi - - if ! run_test $TEST_TYPE zsh -f -i ; then - FAILED=1 - fi - - if ! run_test $TEST_TYPE fish -i ; then - FAILED=1 - fi - - if ! run_test $TEST_TYPE tcsh -f -i ; then - FAILED=1 - fi - - if ! run_test $TEST_TYPE busybox ash -i ; then - FAILED=1 - fi - - if ! run_test $TEST_TYPE mksh -i ; then - FAILED=1 - fi - - if ! run_test $TEST_TYPE dash -i ; then - # dash tests are not stable, see #931 - # FAILED=1 - true - fi - if test $TEST_TYPE == daemon ; then - ./scripts/powerline-daemon -k + echo "> Testing $TEST_TYPE" + for POWERLINE_COMMAND in "" \ + $PWD/scripts/powerline \ + $PWD/scripts/powerline-render \ + "$PYTHON $PWD/client/powerline.py" \ + $PWD/client/powerline.sh + do + case "$POWERLINE_COMMAND" in + *powerline) TEST_CLIENT=C ;; + *powerline-render) TEST_CLIENT=render ;; + *powerline.py) TEST_CLIENT=python ;; + *powerline.sh) TEST_CLIENT=shell ;; + "") TEST_CLIENT=auto ;; + esac + if test "$TEST_CLIENT" = "shell" && ! which socat >/dev/null ; then + continue + fi + if test "$TEST_CLIENT" = render && test "$TEST_TYPE" = daemon ; then + continue + fi + if test "x$COMMAND_PATTERN" != "x" && ! ( + echo "$POWERLINE_COMMAND" | grep -e"$COMMAND_PATTERN" &>/dev/null) + then + continue + fi + export POWERLINE_COMMAND + echo ">> powerline command is ${POWERLINE_COMMAND:-empty}" + for TEST_COMMAND in \ + "bash --norc --noprofile -i" \ + "zsh -f -i" \ + "fish -i" \ + "tcsh -f -i" \ + "busybox ash -i" \ + "mksh -i" \ + "dash -i" + do + SH="${TEST_COMMAND%% *}" + if test "x$ONLY_SHELL" != "x" && test "x$ONLY_SHELL" != "x$SH" ; then + continue + fi + if ! which $SH >/dev/null ; then + continue + fi + echo ">>> $(which $SH)" + if ! run_test $TEST_TYPE $TEST_CLIENT $TEST_COMMAND ; then + # dash tests are not stable, see #931 + if test "x$SH" != "xdash" ; then + FAILED=1 + fi + fi + done + done + if test $TEST_TYPE = daemon ; then + $PYTHON ./scripts/powerline-daemon -k wait $(cat tests/shell/daemon_pid) if ! test -z "$(cat tests/shell/daemon_log)" ; then echo '____________________________________________________________' @@ -240,8 +292,11 @@ if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || te done fi -if ! run_test ipython ipython ; then - FAILED=1 +if test "x${ONLY_SHELL}" = "x" || test "x${ONLY_SHELL}" = "xipython" ; then + echo "> $(which ipython)" + if ! run_test ipython ipython ipython ; then + FAILED=1 + fi fi test $FAILED -eq 0 && rm -r tests/shell From 042d5422311287582b7639e0350bb7833ae73d93 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 23 Aug 2014 03:52:09 +0400 Subject: [PATCH 06/12] Also test whether running daemon is successfull without arguments --- tests/test_shells/test.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/test_shells/test.sh b/tests/test_shells/test.sh index 40990e81..903ac79c 100755 --- a/tests/test_shells/test.sh +++ b/tests/test_shells/test.sh @@ -292,6 +292,23 @@ if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || te done fi +if ! $PYTHON scripts/powerline-daemon &> tests/shell/daemon_log_2 ; then + echo "Daemon exited with status $?" + FAILED=1 +else + sleep 1 + $PYTHON scripts/powerline-daemon -k +fi + +if ! test -z "$(cat tests/shell/daemon_log_2)" ; then + FAILED=1 + echo '____________________________________________________________' + echo "Daemon log (2nd):" + echo '============================================================' + cat tests/shell/daemon_log_2 + FAILED=1 +fi + if test "x${ONLY_SHELL}" = "x" || test "x${ONLY_SHELL}" = "xipython" ; then echo "> $(which ipython)" if ! run_test ipython ipython ipython ; then From 77a7a267826465ffeedb10e4b8f3e095f3fab01a Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 23 Aug 2014 04:43:17 +0400 Subject: [PATCH 07/12] Do not require scripts/powerline It may be immediately moved to bin/ sometimes or not compiled at all for some reason. --- tests/test_shells/test.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/test_shells/test.sh b/tests/test_shells/test.sh index 903ac79c..9053c1e8 100755 --- a/tests/test_shells/test.sh +++ b/tests/test_shells/test.sh @@ -240,6 +240,13 @@ if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || te *powerline.sh) TEST_CLIENT=shell ;; "") TEST_CLIENT=auto ;; esac + if test "$TEST_CLIENT" = "C" && ! test -x scripts/powerline ; then + if which powerline >/dev/null ; then + POWERLINE_COMMAND=powerline + else + continue + fi + fi if test "$TEST_CLIENT" = "shell" && ! which socat >/dev/null ; then continue fi From 0232d3215b207189a727fc66700a4a82d4c3902d Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 23 Aug 2014 14:55:59 +0400 Subject: [PATCH 08/12] Add --socket argument to all clients Makes it not needed to kill daemon for testing, but disables implicit `powerline-config shell command` testing. --- client/powerline.c | 12 +++++++++-- client/powerline.py | 9 ++++++-- client/powerline.sh | 8 +++++++- powerline/shell.py | 1 + scripts/powerline-daemon | 43 ++++++++++++++++++++++++++------------- tests/test_shells/test.sh | 23 +++++++++++++-------- 6 files changed, 68 insertions(+), 28 deletions(-) diff --git a/client/powerline.c b/client/powerline.c index 44819ffe..f53e3457 100644 --- a/client/powerline.c +++ b/client/powerline.c @@ -60,20 +60,28 @@ int main(int argc, char *argv[]) { int i; ptrdiff_t read_size; struct sockaddr_un server; - char address[ADDRESS_SIZE]; + char address_buf[ADDRESS_SIZE]; const char eof[2] = "\0\0"; char num_args[NUM_ARGS_SIZE]; char buf[BUF_SIZE]; char *newargv[NEW_ARGV_SIZE]; char *wd = NULL; char **envp; + const char *address; if (argc < 2) { printf("Must provide at least one argument.\n"); return EXIT_FAILURE; } - snprintf(address, ADDRESS_SIZE, ADDRESS_TEMPLATE, getuid()); + if (argc > 3 && strcmp(argv[1], "--socket") == 0) { + address = argv[2]; + argv += 2; + argc -= 2; + } else { + snprintf(address_buf, ADDRESS_SIZE, ADDRESS_TEMPLATE, getuid()); + address = &(address_buf[0]); + } sd = socket(AF_UNIX, SOCK_STREAM, 0); if (sd == -1) diff --git a/client/powerline.py b/client/powerline.py index 6b76e804..d874b86a 100755 --- a/client/powerline.py +++ b/client/powerline.py @@ -15,10 +15,15 @@ if len(sys.argv) < 2: platform = sys.platform.lower() use_filesystem = 'darwin' in platform -# use_filesystem = True del platform -address = ('/tmp/powerline-ipc-%d' if use_filesystem else '\0powerline-ipc-%d') % os.getuid() +if sys.argv[1] == '--socket': + address = sys.argv[2] + if not use_filesystem: + address = '\0' + address + del sys.argv[1:3] +else: + address = ('/tmp/powerline-ipc-%d' if use_filesystem else '\0powerline-ipc-%d') % os.getuid() sock = socket.socket(family=socket.AF_UNIX) diff --git a/client/powerline.sh b/client/powerline.sh index 5860b7f8..2c85fe77 100755 --- a/client/powerline.sh +++ b/client/powerline.sh @@ -1,6 +1,12 @@ #!/bin/sh -ADDRESS="powerline-ipc-${UID:-`id -u`}" +if test "$1" = "--socket" ; then + shift + ADDRESS="$1" + shift +else + ADDRESS="powerline-ipc-${UID:-`id -u`}" +fi # Warning: env -0 does not work in busybox. Consider switching to parsing # `set` output in this case diff --git a/powerline/shell.py b/powerline/shell.py index 5920f897..7f006e58 100644 --- a/powerline/shell.py +++ b/powerline/shell.py @@ -66,6 +66,7 @@ def get_argparser(parser=None, *args, **kwargs): p.add_argument('-t', '--theme_option', metavar='THEME.KEY.KEY=VALUE', action='append', help='Like above, but theme-specific. THEME should point to an existing and used theme to have any effect, but it is fine to use any theme here.') p.add_argument('-R', '--renderer_arg', metavar='KEY=VAL', action='append', help='Like above, but provides argument for renderer. Is supposed to be used only by shell bindings to provide various data like last_exit_code or last_pipe_status (they are not using --renderer_arg for historical resons: renderer_arg was added later).') p.add_argument('-p', '--config_path', action='append', metavar='PATH', help='Path to configuration directory. If it is present then configuration files will only be seeked in the provided path. May be provided multiple times to search in a list of directories.') + p.add_argument('--socket', metavar='ADDRESS', type=str, help='Socket address to use in daemon clients. Is always UNIX domain socket on linux and file socket on Mac OS X. Not used here, present only for compatibility with other powerline clients. This argument must always be the first one and be in a form `--socket ADDRESS\': no `=\' or short form allowed (in other powerline clients, not here).') return p diff --git a/scripts/powerline-daemon b/scripts/powerline-daemon index 4a8ffb9b..593002df 100755 --- a/scripts/powerline-daemon +++ b/scripts/powerline-daemon @@ -17,20 +17,13 @@ from io import StringIO from powerline.shell import get_argparser, finish_args, ShellPowerline, write_output from powerline.lib.monotonic import monotonic + is_daemon = False platform = sys.platform.lower() use_filesystem = 'darwin' in platform -# use_filesystem = True -del platform -if use_filesystem: - address = '/tmp/powerline-ipc-%d' - pidfile = address + '.pid' -else: - # Use the abstract namespace for sockets rather than the filesystem - # (Available only in linux) - address = '\0powerline-ipc-%d' -address = address % os.getuid() +address = None +pidfile = None class NonInteractiveArgParser(ArgumentParser): @@ -334,8 +327,11 @@ def lockpidfile(): import fcntl import atexit import stat - fd = os.open(pidfile, os.O_WRONLY | os.O_CREAT, - stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH) + fd = os.open( + pidfile, + os.O_WRONLY | os.O_CREAT, + stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH + ) try: fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB) except EnvironmentError: @@ -352,15 +348,34 @@ def lockpidfile(): def main(): - p = ArgumentParser(description= - 'Daemon to improve the performance of powerline') + global address + global pidfile + p = ArgumentParser(description='Daemon to improve the performance of powerline') p.add_argument('--quiet', '-q', action='store_true', help='Without other options: do not complain about already running powerline-daemon instance. Will still exit with 1. With `--kill\' and `--replace\': do not show any messages. With `--foreground\': ignored. Does not silence exceptions in any case.') + p.add_argument('--socket', '-s', help='Specify socket which will be used for connecting to daemon.') a = p.add_mutually_exclusive_group().add_argument a('--kill', '-k', action='store_true', help='Kill an already running instance') a('--foreground', '-f', action='store_true', help='Run in the foreground (dont daemonize)') a('--replace', '-r', action='store_true', help='Replace an already running instance') args = p.parse_args() + if args.socket: + address = args.socket + if not use_filesystem: + address = '\0' + address + else: + if use_filesystem: + address = '/tmp/powerline-ipc-%d' + else: + # Use the abstract namespace for sockets rather than the filesystem + # (Available only in linux) + address = '\0powerline-ipc-%d' + + address = address % os.getuid() + + if use_filesystem: + pidfile = address + '.pid' + if args.kill: if kill_daemon(): if not args.quiet: diff --git a/tests/test_shells/test.sh b/tests/test_shells/test.sh index 9053c1e8..9f65aff0 100755 --- a/tests/test_shells/test.sh +++ b/tests/test_shells/test.sh @@ -16,6 +16,7 @@ ONLY_SHELL: execute only tests for given shell ONLY_TEST_TYPE: execute only "daemon" or "nodaemon" tests COMMAND_PATTERN: use only commands that match given pattern for testing EOF +exit 0 fi check_screen_log() { @@ -213,21 +214,25 @@ done unset ENV -if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || test "x${ONLY_SHELL}" = xbusybox ; then - powerline-daemon -k || true - sleep 1s +export ADDRESS="powerline-ipc-test-$RANDOM" +export PYTHON +echo "Powerline address: $ADDRESS" +if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || test "x${ONLY_SHELL}" = xbusybox ; then scripts/powerline-config shell command for TEST_TYPE in "daemon" "nodaemon" ; do if test $TEST_TYPE = daemon ; then - sh -c 'echo $$ > tests/shell/daemon_pid; $PYTHON ./scripts/powerline-daemon -f &>tests/shell/daemon_log' & + sh -c ' + echo $$ > tests/shell/daemon_pid + $PYTHON ./scripts/powerline-daemon -s$ADDRESS -f &>tests/shell/daemon_log + ' & fi if test "x$ONLY_TEST_TYPE" != "x" && test "x$ONLY_TEST_TYPE" != "x$TEST_TYPE" ; then continue fi echo "> Testing $TEST_TYPE" - for POWERLINE_COMMAND in "" \ + for POWERLINE_COMMAND in \ $PWD/scripts/powerline \ $PWD/scripts/powerline-render \ "$PYTHON $PWD/client/powerline.py" \ @@ -238,7 +243,6 @@ if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || te *powerline-render) TEST_CLIENT=render ;; *powerline.py) TEST_CLIENT=python ;; *powerline.sh) TEST_CLIENT=shell ;; - "") TEST_CLIENT=auto ;; esac if test "$TEST_CLIENT" = "C" && ! test -x scripts/powerline ; then if which powerline >/dev/null ; then @@ -258,6 +262,7 @@ if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || te then continue fi + POWERLINE_COMMAND="$POWERLINE_COMMAND --socket $ADDRESS" export POWERLINE_COMMAND echo ">> powerline command is ${POWERLINE_COMMAND:-empty}" for TEST_COMMAND in \ @@ -286,7 +291,7 @@ if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || te done done if test $TEST_TYPE = daemon ; then - $PYTHON ./scripts/powerline-daemon -k + $PYTHON ./scripts/powerline-daemon -s$ADDRESS -k wait $(cat tests/shell/daemon_pid) if ! test -z "$(cat tests/shell/daemon_log)" ; then echo '____________________________________________________________' @@ -299,12 +304,12 @@ if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || te done fi -if ! $PYTHON scripts/powerline-daemon &> tests/shell/daemon_log_2 ; then +if ! $PYTHON scripts/powerline-daemon -s$ADDRESS &> tests/shell/daemon_log_2 ; then echo "Daemon exited with status $?" FAILED=1 else sleep 1 - $PYTHON scripts/powerline-daemon -k + $PYTHON scripts/powerline-daemon -s$ADDRESS -k fi if ! test -z "$(cat tests/shell/daemon_log_2)" ; then From 9b7052bf3ee23de19cd0ed0f57fb8417edf3f6e4 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 23 Aug 2014 15:16:30 +0400 Subject: [PATCH 09/12] Do not execute all tests in travis --- tests/test.sh | 2 +- tests/test_shells/test.sh | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/tests/test.sh b/tests/test.sh index f25d63a6..129e0b5e 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -20,7 +20,7 @@ for script in tests/*.vim ; do FAILED=1 fi done -if ! bash tests/test_shells/test.sh ; then +if ! bash tests/test_shells/test.sh --fast ; then echo "Failed shells" if ${PYTHON} -c 'import platform, sys; sys.exit(1 * (platform.python_implementation() == "PyPy"))' ; then FAILED=1 diff --git a/tests/test_shells/test.sh b/tests/test_shells/test.sh index 9f65aff0..8f3e0d0c 100755 --- a/tests/test_shells/test.sh +++ b/tests/test_shells/test.sh @@ -1,10 +1,18 @@ #!/bin/bash : ${PYTHON:=python} FAILED=0 +if test "x$1" = "x--fast" ; then + FAST=1 + shift +fi ONLY_SHELL="$1" ONLY_TEST_TYPE="$2" COMMAND_PATTERN="$3" +if ! test -z "$ONLY_SHELL$ONLY_TEST_TYPE$COMMAND_PATTERN" ; then + FAST= +fi + export PYTHON if test "x$ONLY_SHELL" = "x--help" ; then @@ -222,6 +230,16 @@ if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || te scripts/powerline-config shell command for TEST_TYPE in "daemon" "nodaemon" ; do + if test x$FAST = x1 ; then + if test $TEST_TYPE = daemon ; then + VARIANTS=3 + else + VARIANTS=4 + fi + EXETEST="$(( ${RANDOM:-`date +%N | sed s/^0*//`} % $VARIANTS ))" + echo "Execute tests: $EXETEST" + fi + if test $TEST_TYPE = daemon ; then sh -c ' echo $$ > tests/shell/daemon_pid @@ -232,6 +250,7 @@ if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || te continue fi echo "> Testing $TEST_TYPE" + I=-1 for POWERLINE_COMMAND in \ $PWD/scripts/powerline \ $PWD/scripts/powerline-render \ @@ -244,6 +263,10 @@ if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || te *powerline.py) TEST_CLIENT=python ;; *powerline.sh) TEST_CLIENT=shell ;; esac + if test "$TEST_CLIENT" = render && test "$TEST_TYPE" = daemon ; then + continue + fi + I="$(( I + 1 ))" if test "$TEST_CLIENT" = "C" && ! test -x scripts/powerline ; then if which powerline >/dev/null ; then POWERLINE_COMMAND=powerline @@ -254,9 +277,6 @@ if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || te if test "$TEST_CLIENT" = "shell" && ! which socat >/dev/null ; then continue fi - if test "$TEST_CLIENT" = render && test "$TEST_TYPE" = daemon ; then - continue - fi if test "x$COMMAND_PATTERN" != "x" && ! ( echo "$POWERLINE_COMMAND" | grep -e"$COMMAND_PATTERN" &>/dev/null) then @@ -265,6 +285,7 @@ if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || te POWERLINE_COMMAND="$POWERLINE_COMMAND --socket $ADDRESS" export POWERLINE_COMMAND echo ">> powerline command is ${POWERLINE_COMMAND:-empty}" + J=-1 for TEST_COMMAND in \ "bash --norc --noprofile -i" \ "zsh -f -i" \ @@ -274,6 +295,12 @@ if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || te "mksh -i" \ "dash -i" do + J="$(( J + 1 ))" + if test x$FAST = x1 ; then + if test $(( (I + J) % $VARIANTS )) -ne $EXETEST ; then + continue + fi + fi SH="${TEST_COMMAND%% *}" if test "x$ONLY_SHELL" != "x" && test "x$ONLY_SHELL" != "x$SH" ; then continue From ebc98977aef7552b546f4b98b5478818692ec28a Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 23 Aug 2014 15:18:00 +0400 Subject: [PATCH 10/12] Make test_shells/test.sh compatible with dash --- tests/test_shells/test.sh | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/test_shells/test.sh b/tests/test_shells/test.sh index 8f3e0d0c..f495708b 100755 --- a/tests/test_shells/test.sh +++ b/tests/test_shells/test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh : ${PYTHON:=python} FAILED=0 if test "x$1" = "x--fast" ; then @@ -84,11 +84,10 @@ run_test() { shift SH="$1" SESNAME="powerline-shell-test-${SH}-$$" - ARGS=( "$@" ) run "${TEST_TYPE}" "${TEST_CLIENT}" "${SH}" \ screen -L -c tests/test_shells/screenrc -d -m -S "$SESNAME" \ - env LANG=en_US.UTF-8 BINDFILE="$BINDFILE" "${ARGS[@]}" + env LANG=en_US.UTF-8 BINDFILE="$BINDFILE" "$@" while ! screen -S "$SESNAME" -X readreg a tests/test_shells/input.$SH ; do sleep 0.1s done @@ -105,7 +104,7 @@ run_test() { # … # prompt1> prompt2> … while read -r line ; do - screen -S "$SESNAME" -p 0 -X stuff "$line"$'\n' + screen -S "$SESNAME" -p 0 -X stuff "$line"$(printf '\r') sleep 1 done < tests/test_shells/input.$SH else @@ -222,7 +221,7 @@ done unset ENV -export ADDRESS="powerline-ipc-test-$RANDOM" +export ADDRESS="powerline-ipc-test-$$" export PYTHON echo "Powerline address: $ADDRESS" From 1b56179676edb6f9d0064ea85aed323630cf3ba0 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 23 Aug 2014 16:02:04 +0400 Subject: [PATCH 11/12] Disable dash tests in travis --- tests/test_shells/test.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/test_shells/test.sh b/tests/test_shells/test.sh index f495708b..64f9146f 100755 --- a/tests/test_shells/test.sh +++ b/tests/test_shells/test.sh @@ -301,6 +301,10 @@ if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || te fi fi SH="${TEST_COMMAND%% *}" + # dash tests are not stable, see #931 + if test x$FAST$SH = x1dash ; then + continue + fi if test "x$ONLY_SHELL" != "x" && test "x$ONLY_SHELL" != "x$SH" ; then continue fi @@ -309,10 +313,7 @@ if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || te fi echo ">>> $(which $SH)" if ! run_test $TEST_TYPE $TEST_CLIENT $TEST_COMMAND ; then - # dash tests are not stable, see #931 - if test "x$SH" != "xdash" ; then - FAILED=1 - fi + FAILED=1 fi done done From 20e9575c176b4520d1cfd7e87a9a92386e09c190 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 23 Aug 2014 16:24:16 +0400 Subject: [PATCH 12/12] Do not try to test ipython if it is not available --- tests/test_shells/test.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/test_shells/test.sh b/tests/test_shells/test.sh index 64f9146f..9104fa99 100755 --- a/tests/test_shells/test.sh +++ b/tests/test_shells/test.sh @@ -349,9 +349,11 @@ if ! test -z "$(cat tests/shell/daemon_log_2)" ; then fi if test "x${ONLY_SHELL}" = "x" || test "x${ONLY_SHELL}" = "xipython" ; then - echo "> $(which ipython)" - if ! run_test ipython ipython ipython ; then - FAILED=1 + if which ipython >/dev/null ; then + echo "> $(which ipython)" + if ! run_test ipython ipython ipython ; then + FAILED=1 + fi fi fi