Add files from @kovidgoyal's powerline-daemon repo
Minor changes have been applied: - Removed copyright info and GPL 3 license since Powerline is MIT (needs confirmation from kovidgoyal before merge) - The `powerline-client` script is renamed to `powerline`, and calls the daemon or `powerline-render` (the previous `powerline`) to render a statusline - Minor coding style corrections to match the rest of the project - Python 3 support is removed for now due to setuptools failing with binary scripts Todo: - Automatically attempt to launch powerline-daemon the first time powerline is run if the daemon isn't already running? - pip install -e fails with binary files (it appears that pip recodes the powerline binary to ASCII, the compiled powerline script must be copied manually to ~/.local/bin after pip install -e has been run)
This commit is contained in:
parent
6430877ec9
commit
a122e73b9b
Binary file not shown.
|
@ -0,0 +1,115 @@
|
|||
/* vim:fileencoding=utf-8:noet */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define handle_error(msg) \
|
||||
do { perror(msg); exit(EXIT_FAILURE); } while (0)
|
||||
|
||||
#ifndef TEMP_FAILURE_RETRY
|
||||
#define TEMP_FAILURE_RETRY(expression) \
|
||||
( \
|
||||
({ long int __result; \
|
||||
do __result = (long int) (expression); \
|
||||
while (__result == -1L && errno == EINTR); \
|
||||
__result; }))
|
||||
#endif
|
||||
|
||||
extern char **environ;
|
||||
|
||||
void do_write(int sd, const char *raw, int len) {
|
||||
int written = 0, n = -1;
|
||||
|
||||
while (written < len) {
|
||||
n = TEMP_FAILURE_RETRY(write(sd, raw+written, len-written));
|
||||
if (n == -1) {
|
||||
close(sd);
|
||||
handle_error("write() failed");
|
||||
}
|
||||
written += n;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int sd = -1, i;
|
||||
struct sockaddr_un server;
|
||||
char address[50] = {};
|
||||
const char eof[2] = "\0\0";
|
||||
char buf[4096] = {};
|
||||
char *newargv[200] = {};
|
||||
char *wd = NULL;
|
||||
char **envp;
|
||||
|
||||
if (argc < 2) { printf("Must provide at least one argument.\n"); return EXIT_FAILURE; }
|
||||
|
||||
#ifdef __APPLE__
|
||||
snprintf(address, 50, "/tmp/powerline-ipc-%d", getuid());
|
||||
#else
|
||||
snprintf(address, 50, "powerline-ipc-%d", getuid());
|
||||
#endif
|
||||
|
||||
sd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (sd == -1) handle_error("socket() failed");
|
||||
|
||||
memset(&server, 0, sizeof(struct sockaddr_un)); // Clear
|
||||
server.sun_family = AF_UNIX;
|
||||
#ifdef __APPLE__
|
||||
strncpy(server.sun_path, address, strlen(address));
|
||||
#else
|
||||
strncpy(server.sun_path+1, address, strlen(address));
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
if (connect(sd, (struct sockaddr *) &server, sizeof(server.sun_family) + strlen(address)) < 0) {
|
||||
#else
|
||||
if (connect(sd, (struct sockaddr *) &server, sizeof(server.sun_family) + strlen(address)+1) < 0) {
|
||||
#endif
|
||||
close(sd);
|
||||
// We failed to connect to the daemon, execute powerline instead
|
||||
argc = (argc < 199) ? argc : 199;
|
||||
for (i=1; i < argc; i++) newargv[i] = argv[i];
|
||||
newargv[0] = "powerline-render";
|
||||
newargv[argc] = NULL;
|
||||
execvp("powerline-render", newargv);
|
||||
}
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
do_write(sd, argv[i], strlen(argv[i]));
|
||||
do_write(sd, eof, 1);
|
||||
}
|
||||
|
||||
for(envp=environ; *envp; envp++) {
|
||||
do_write(sd, "--env=", 6);
|
||||
do_write(sd, *envp, strlen(*envp));
|
||||
do_write(sd, eof, 1);
|
||||
}
|
||||
|
||||
wd = getcwd(NULL, 0);
|
||||
if (wd != NULL) {
|
||||
do_write(sd, "--cwd=", 6);
|
||||
do_write(sd, wd, strlen(wd));
|
||||
free(wd); wd = NULL;
|
||||
}
|
||||
|
||||
do_write(sd, eof, 2);
|
||||
|
||||
i = -1;
|
||||
while (i != 0) {
|
||||
i = TEMP_FAILURE_RETRY(read(sd, buf, 4096));
|
||||
if (i == -1) {
|
||||
close(sd);
|
||||
handle_error("read() failed");
|
||||
}
|
||||
if (i > 0)
|
||||
write(STDOUT_FILENO, buf, i) || 0;
|
||||
}
|
||||
|
||||
close(sd);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8:noet
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
|
||||
import sys
|
||||
import socket
|
||||
import os
|
||||
import errno
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print('Must provide at least one argument.', file=sys.stderr)
|
||||
raise SystemExit(1)
|
||||
|
||||
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()
|
||||
|
||||
sock = socket.socket(family=socket.AF_UNIX)
|
||||
|
||||
|
||||
def eintr_retry_call(func, *args, **kwargs):
|
||||
while True:
|
||||
try:
|
||||
return func(*args, **kwargs)
|
||||
except EnvironmentError as e:
|
||||
if getattr(e, 'errno', None) == errno.EINTR:
|
||||
continue
|
||||
raise
|
||||
|
||||
try:
|
||||
eintr_retry_call(sock.connect, address)
|
||||
except Exception:
|
||||
# Run the powerline renderer
|
||||
args = ['powerline-render'] + sys.argv[1:]
|
||||
os.execvp('powerline-render', args)
|
||||
|
||||
fenc = sys.getfilesystemencoding() or 'utf-8'
|
||||
if fenc == 'ascii':
|
||||
fenc = 'utf-8'
|
||||
|
||||
args = [x.encode(fenc) if isinstance(x, type('')) else x for x in sys.argv[1:]]
|
||||
|
||||
try:
|
||||
cwd = os.getcwd()
|
||||
except EnvironmentError:
|
||||
pass
|
||||
else:
|
||||
if isinstance(cwd, type('')):
|
||||
cwd = cwd.encode(fenc)
|
||||
args.append(b'--cwd=' + cwd)
|
||||
|
||||
|
||||
env = (k + '=' + 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((b'--env=' + x for x in env))
|
||||
|
||||
EOF = b'\0\0'
|
||||
|
||||
for a in args:
|
||||
eintr_retry_call(sock.sendall, a + EOF[0])
|
||||
|
||||
eintr_retry_call(sock.sendall, EOF)
|
||||
|
||||
received = []
|
||||
while True:
|
||||
r = sock.recv(4096)
|
||||
if not r:
|
||||
break
|
||||
received.append(r)
|
||||
|
||||
sock.close()
|
||||
|
||||
print (b''.join(received))
|
|
@ -0,0 +1 @@
|
|||
powerline
|
|
@ -0,0 +1,395 @@
|
|||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8:noet
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
|
||||
import socket
|
||||
import os
|
||||
import errno
|
||||
import sys
|
||||
from argparse import ArgumentParser
|
||||
from select import select
|
||||
from signal import signal, SIGTERM
|
||||
from time import sleep
|
||||
from functools import partial
|
||||
from locale import getpreferredencoding
|
||||
|
||||
from powerline.shell import get_argparser, finish_args, ShellPowerline
|
||||
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()
|
||||
|
||||
|
||||
class NonInteractiveArgParser(ArgumentParser):
|
||||
def print_usage(self, file=None):
|
||||
raise Exception(self.format_usage())
|
||||
|
||||
def print_help(self, file=None):
|
||||
raise Exception(self.format_help())
|
||||
|
||||
def exit(self, status=0, message=None):
|
||||
pass
|
||||
|
||||
def error(self, message):
|
||||
raise Exception(self.format_usage())
|
||||
|
||||
|
||||
parser = get_argparser(parser=NonInteractiveArgParser, description='powerline daemon')
|
||||
parser.add_argument('--cwd', metavar='PATH')
|
||||
parser.add_argument('--env', action='append')
|
||||
|
||||
EOF = b'EOF\0\0'
|
||||
|
||||
powerlines = {}
|
||||
logger = None
|
||||
config_loader = None
|
||||
home = os.path.expanduser('~')
|
||||
|
||||
|
||||
class PowerlineDaemon(ShellPowerline):
|
||||
def get_log_handler(self):
|
||||
if not is_daemon:
|
||||
import logging
|
||||
return logging.StreamHandler()
|
||||
return super(PowerlineDaemon, self).get_log_handler()
|
||||
|
||||
|
||||
def render(args):
|
||||
global logger
|
||||
global config_loader
|
||||
environ = dict(((k, v) for k, v in (x.partition('=')[0::2] for x in args.env)))
|
||||
cwd = environ.get('PWD', args.cwd or '/')
|
||||
segment_info = {
|
||||
'getcwd': lambda: cwd,
|
||||
'home': environ.get('HOME', home),
|
||||
'environ': environ,
|
||||
'args': args,
|
||||
}
|
||||
key = (args.ext[0], args.renderer_module,
|
||||
tuple(args.config) if args.config else None,
|
||||
tuple(args.theme_option) if args.theme_option else None,)
|
||||
if args.renderer_arg:
|
||||
segment_info.update(args.renderer_arg)
|
||||
finish_args(args)
|
||||
pl = None
|
||||
try:
|
||||
pl = powerlines[key]
|
||||
except KeyError:
|
||||
try:
|
||||
pl = powerlines[key] = PowerlineDaemon(
|
||||
args,
|
||||
logger=logger,
|
||||
config_loader=config_loader
|
||||
)
|
||||
except SystemExit:
|
||||
# Somebody thought raising system exit was a good idea,
|
||||
return ''
|
||||
except Exception as e:
|
||||
if pl:
|
||||
pl.pl.exception('Failed to render {0}: {1}', str(key), str(e))
|
||||
else:
|
||||
return 'Failed to render {0}: {1}'.format(str(key), str(e))
|
||||
if logger is None:
|
||||
logger = pl.logger
|
||||
if config_loader is None:
|
||||
config_loader = pl.config_loader
|
||||
return pl.render(width=args.width, side=args.side, segment_info=segment_info)
|
||||
|
||||
|
||||
def eintr_retry_call(func, *args, **kwargs):
|
||||
while True:
|
||||
try:
|
||||
return func(*args, **kwargs)
|
||||
except EnvironmentError as e:
|
||||
if getattr(e, 'errno', None) == errno.EINTR:
|
||||
continue
|
||||
raise
|
||||
|
||||
|
||||
def do_read(conn, timeout=2.0):
|
||||
''' Read data from the client. If the client fails to send data within
|
||||
timeout seconds, abort. '''
|
||||
read = []
|
||||
end_time = monotonic() + timeout
|
||||
while not read or not read[-1].endswith(b'\0\0'):
|
||||
r, w, e = select((conn,), (), (conn,), timeout)
|
||||
if e:
|
||||
return
|
||||
if monotonic() > end_time:
|
||||
return
|
||||
if not r:
|
||||
continue
|
||||
x = eintr_retry_call(conn.recv, 4096)
|
||||
if x:
|
||||
read.append(x)
|
||||
else:
|
||||
break
|
||||
return b''.join(read)
|
||||
|
||||
|
||||
def do_write(conn, result):
|
||||
try:
|
||||
eintr_retry_call(conn.sendall, result + b'\0')
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
encoding = getpreferredencoding() or 'UTF-8'
|
||||
if encoding.lower() == 'ascii':
|
||||
encoding = 'UTF-8'
|
||||
|
||||
|
||||
def safe_bytes(o, encoding=encoding):
|
||||
'''Return bytes instance without ever throwing an exception.'''
|
||||
try:
|
||||
try:
|
||||
# We are assuming that o is a unicode object
|
||||
return o.encode(encoding, 'replace')
|
||||
except Exception:
|
||||
# Object may have defined __bytes__ (python 3) or __str__ method
|
||||
# (python 2)
|
||||
# This also catches problem with non_ascii_bytes.encode('utf-8')
|
||||
# that first tries to decode to UTF-8 using ascii codec (and fails
|
||||
# in this case) and then encode to given encoding: errors= argument
|
||||
# is not used in the first stage.
|
||||
return bytes(o)
|
||||
except Exception as e:
|
||||
return safe_bytes(str(e), encoding)
|
||||
|
||||
|
||||
def do_render(req):
|
||||
try:
|
||||
args = [x.decode(encoding) for x in req.split(b'\0') if x]
|
||||
args = parser.parse_args(args)
|
||||
return safe_bytes(render(args))
|
||||
except Exception as e:
|
||||
return safe_bytes(str(e))
|
||||
|
||||
|
||||
def do_one(sock, read_sockets, write_sockets, result_map):
|
||||
r, w, e = select(
|
||||
tuple(read_sockets) + (sock,),
|
||||
tuple(write_sockets),
|
||||
tuple(read_sockets) + tuple(write_sockets) + (sock,),
|
||||
60.0
|
||||
)
|
||||
|
||||
if sock in e:
|
||||
# We cannot accept any more connections, so we exit
|
||||
raise SystemExit(1)
|
||||
|
||||
for s in e:
|
||||
# Discard all broken connections to clients
|
||||
s.close()
|
||||
read_sockets.discard(s)
|
||||
write_sockets.discard(s)
|
||||
|
||||
for s in r:
|
||||
if s == sock:
|
||||
# A client wants to connect
|
||||
conn, _ = eintr_retry_call(sock.accept)
|
||||
read_sockets.add(conn)
|
||||
else:
|
||||
# A client has sent some data
|
||||
read_sockets.discard(s)
|
||||
req = do_read(s)
|
||||
if req == EOF:
|
||||
raise SystemExit(0)
|
||||
elif req:
|
||||
ans = do_render(req)
|
||||
result_map[s] = ans
|
||||
write_sockets.add(s)
|
||||
else:
|
||||
s.close()
|
||||
|
||||
for s in w:
|
||||
# A client is ready to receive the result
|
||||
write_sockets.discard(s)
|
||||
result = result_map.pop(s)
|
||||
try:
|
||||
do_write(s, result)
|
||||
finally:
|
||||
s.close()
|
||||
|
||||
|
||||
def main_loop(sock):
|
||||
sock.listen(1)
|
||||
sock.setblocking(0)
|
||||
|
||||
read_sockets, write_sockets = set(), set()
|
||||
result_map = {}
|
||||
try:
|
||||
while True:
|
||||
do_one(sock, read_sockets, write_sockets, result_map)
|
||||
except KeyboardInterrupt:
|
||||
raise SystemExit(0)
|
||||
return 0
|
||||
|
||||
|
||||
def daemonize(stdin=os.devnull, stdout=os.devnull, stderr=os.devnull):
|
||||
try:
|
||||
pid = os.fork()
|
||||
if pid > 0:
|
||||
# exit first parent
|
||||
sys.exit(0)
|
||||
except OSError as e:
|
||||
print ("fork #1 failed: %d (%s)" % (e.errno, e.strerror), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
# decouple from parent environment
|
||||
os.chdir("/")
|
||||
os.setsid()
|
||||
os.umask(0)
|
||||
|
||||
# do second fork
|
||||
try:
|
||||
pid = os.fork()
|
||||
if pid > 0:
|
||||
# exit from second parent
|
||||
sys.exit(0)
|
||||
except OSError as e:
|
||||
print ("fork #2 failed: %d (%s)" % (e.errno, e.strerror), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
# Redirect standard file descriptors.
|
||||
si = file(stdin, 'r')
|
||||
so = file(stdout, 'a+')
|
||||
se = file(stderr, 'a+', 0)
|
||||
os.dup2(si.fileno(), sys.stdin.fileno())
|
||||
os.dup2(so.fileno(), sys.stdout.fileno())
|
||||
os.dup2(se.fileno(), sys.stderr.fileno())
|
||||
global is_daemon
|
||||
is_daemon = True
|
||||
|
||||
|
||||
def check_existing():
|
||||
if use_filesystem:
|
||||
# We cannot bind if the socket file already exists so remove it, we
|
||||
# already have a lock on pidfile, so this should be safe.
|
||||
try:
|
||||
os.unlink(address)
|
||||
except EnvironmentError:
|
||||
pass
|
||||
|
||||
sock = socket.socket(family=socket.AF_UNIX)
|
||||
try:
|
||||
sock.bind(address)
|
||||
except socket.error as e:
|
||||
if getattr(e, 'errno', None) == errno.EADDRINUSE:
|
||||
return None
|
||||
raise
|
||||
return sock
|
||||
|
||||
|
||||
def test_connect():
|
||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
try:
|
||||
try:
|
||||
eintr_retry_call(sock.connect, address)
|
||||
except socket.error:
|
||||
return False
|
||||
else:
|
||||
eintr_retry_call(sock.sendall, EOF)
|
||||
finally:
|
||||
sock.close()
|
||||
return True
|
||||
|
||||
|
||||
def cleanup_lockfile(fd, *args):
|
||||
try:
|
||||
# Remove the directory entry for the lock file
|
||||
os.unlink(pidfile)
|
||||
# Close the file descriptor
|
||||
os.close(fd)
|
||||
except EnvironmentError:
|
||||
pass
|
||||
if args:
|
||||
# Called in signal handler
|
||||
raise SystemExit(1)
|
||||
|
||||
|
||||
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)
|
||||
try:
|
||||
fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||
except EnvironmentError:
|
||||
os.close(fd)
|
||||
return None
|
||||
os.lseek(fd, 0, os.SEEK_SET)
|
||||
os.ftruncate(fd, 0)
|
||||
os.write(fd, ('%d' % os.getpid()).encode('ascii'))
|
||||
os.fsync(fd)
|
||||
cleanup = partial(cleanup_lockfile, fd)
|
||||
signal(SIGTERM, cleanup)
|
||||
atexit.register(cleanup)
|
||||
return fd
|
||||
|
||||
|
||||
def main():
|
||||
p = ArgumentParser(description=
|
||||
'Daemon to improve the performance of powerline')
|
||||
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.kill:
|
||||
if test_connect():
|
||||
print ('Kill command sent to daemon, if it does not die in a couple of seconds use kill to kill it')
|
||||
else:
|
||||
print ('No running daemon found')
|
||||
return
|
||||
|
||||
if args.replace:
|
||||
while test_connect():
|
||||
print ('Kill command sent to daemon, waiting for daemon to exit, press Ctrl-C to terminate wait and exit')
|
||||
sleep(2)
|
||||
|
||||
if use_filesystem and not args.foreground:
|
||||
# We must daemonize before creating the locked pidfile, unfortunately,
|
||||
# this means further print statements are discarded
|
||||
daemonize()
|
||||
|
||||
if use_filesystem:
|
||||
# Create a locked pid file containing the daemon's PID
|
||||
if lockpidfile() is None:
|
||||
print ('The daemon is already running. Use %s -k to kill it.' % os.path.basename(sys.argv[0]),
|
||||
file=sys.stderr)
|
||||
raise SystemExit(1)
|
||||
|
||||
# Bind to address or bail if we cannot bind
|
||||
sock = check_existing()
|
||||
if sock is None:
|
||||
print ('The daemon is already running. Use %s -k to kill it.' % os.path.basename(sys.argv[0]),
|
||||
file=sys.stderr)
|
||||
raise SystemExit(1)
|
||||
|
||||
if args.foreground:
|
||||
return main_loop(sock)
|
||||
|
||||
if not use_filesystem:
|
||||
# We daemonize on linux
|
||||
daemonize()
|
||||
|
||||
main_loop(sock)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
36
setup.py
36
setup.py
|
@ -3,16 +3,42 @@
|
|||
from __future__ import unicode_literals
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
here = os.path.abspath(os.path.dirname(__file__))
|
||||
CURRENT_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
try:
|
||||
README = open(os.path.join(here, 'README.rst'), 'rb').read().decode('utf-8')
|
||||
README = open(os.path.join(CURRENT_DIR, 'README.rst'), 'rb').read().decode('utf-8')
|
||||
except IOError:
|
||||
README = ''
|
||||
|
||||
old_python = sys.version_info < (2, 7)
|
||||
OLD_PYTHON = sys.version_info < (2, 7)
|
||||
|
||||
|
||||
def compile_client():
|
||||
'''Compile the C powerline-client script.'''
|
||||
|
||||
if hasattr(sys, 'getwindowsversion'):
|
||||
raise NotImplementedError()
|
||||
if sys.version_info >= (3, 0):
|
||||
# FIXME Python 3 doesn't allow compiled C files to be included in the
|
||||
# scripts list below. This is because Python 3 distutils tries to
|
||||
# decode the file to ASCII, and fails when powerline-client is
|
||||
# a binary.
|
||||
raise NotImplementedError()
|
||||
else:
|
||||
from distutils.ccompiler import new_compiler
|
||||
compiler = new_compiler().compiler
|
||||
subprocess.check_call(compiler + ['-O3', 'client/powerline.c', '-o', 'scripts/powerline'])
|
||||
|
||||
try:
|
||||
compile_client()
|
||||
except Exception:
|
||||
# FIXME Catch more specific exceptions
|
||||
import shutil
|
||||
print('Compiling C version of powerline-client failed, using Python version instead')
|
||||
shutil.copyfile('client/powerline.py', 'scripts/powerline')
|
||||
|
||||
setup(
|
||||
name='Powerline',
|
||||
|
@ -26,6 +52,8 @@ setup(
|
|||
scripts=[
|
||||
'scripts/powerline',
|
||||
'scripts/powerline-lint',
|
||||
'scripts/powerline-daemon',
|
||||
'scripts/powerline-render',
|
||||
'scripts/powerline-config',
|
||||
],
|
||||
keywords='',
|
||||
|
@ -38,5 +66,5 @@ setup(
|
|||
'Sphinx',
|
||||
],
|
||||
},
|
||||
test_suite='tests' if not old_python else None,
|
||||
test_suite='tests' if not OLD_PYTHON else None,
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue