Rework how the devshell functions
In the new implementation, each known terminal is defined as a class in
oe.terminal, as a subclass of bb.process.Popen. terminal.bbclass wraps this
functionality, providing the metadata pieces. It obeys the OE_TERMINAL
variable, which is a 'choice' typed variable. This variable may be 'auto',
'none', or any of the names of the defined terminals.
When using 'auto', or requesting an unsupported terminal, we attempt to spawn
them in priority order until we get one that's available on this system (and
in the case of the X terminals, has DISPLAY defined). The 'none' value is
used when we're doing things like automated builds, and want to ensure that no
terminal is *ever* spawned, under any circumstances.
Current available terminals:
gnome
konsole
xterm
rxvt
screen
(From OE-Core rev: 69f77f80965fa06a057837f8f49eda06855c4086)
Signed-off-by: Chris Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2011-03-29 19:53:19 +00:00
|
|
|
import logging
|
|
|
|
import oe.classutils
|
|
|
|
import shlex
|
|
|
|
from bb.process import Popen, ExecutionError
|
2015-02-25 11:22:24 +00:00
|
|
|
from distutils.version import LooseVersion
|
Rework how the devshell functions
In the new implementation, each known terminal is defined as a class in
oe.terminal, as a subclass of bb.process.Popen. terminal.bbclass wraps this
functionality, providing the metadata pieces. It obeys the OE_TERMINAL
variable, which is a 'choice' typed variable. This variable may be 'auto',
'none', or any of the names of the defined terminals.
When using 'auto', or requesting an unsupported terminal, we attempt to spawn
them in priority order until we get one that's available on this system (and
in the case of the X terminals, has DISPLAY defined). The 'none' value is
used when we're doing things like automated builds, and want to ensure that no
terminal is *ever* spawned, under any circumstances.
Current available terminals:
gnome
konsole
xterm
rxvt
screen
(From OE-Core rev: 69f77f80965fa06a057837f8f49eda06855c4086)
Signed-off-by: Chris Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2011-03-29 19:53:19 +00:00
|
|
|
|
|
|
|
logger = logging.getLogger('BitBake.OE.Terminal')
|
|
|
|
|
|
|
|
|
2013-05-07 12:56:00 +00:00
|
|
|
class UnsupportedTerminal(Exception):
|
Rework how the devshell functions
In the new implementation, each known terminal is defined as a class in
oe.terminal, as a subclass of bb.process.Popen. terminal.bbclass wraps this
functionality, providing the metadata pieces. It obeys the OE_TERMINAL
variable, which is a 'choice' typed variable. This variable may be 'auto',
'none', or any of the names of the defined terminals.
When using 'auto', or requesting an unsupported terminal, we attempt to spawn
them in priority order until we get one that's available on this system (and
in the case of the X terminals, has DISPLAY defined). The 'none' value is
used when we're doing things like automated builds, and want to ensure that no
terminal is *ever* spawned, under any circumstances.
Current available terminals:
gnome
konsole
xterm
rxvt
screen
(From OE-Core rev: 69f77f80965fa06a057837f8f49eda06855c4086)
Signed-off-by: Chris Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2011-03-29 19:53:19 +00:00
|
|
|
pass
|
|
|
|
|
2013-05-07 12:56:00 +00:00
|
|
|
class NoSupportedTerminals(Exception):
|
Rework how the devshell functions
In the new implementation, each known terminal is defined as a class in
oe.terminal, as a subclass of bb.process.Popen. terminal.bbclass wraps this
functionality, providing the metadata pieces. It obeys the OE_TERMINAL
variable, which is a 'choice' typed variable. This variable may be 'auto',
'none', or any of the names of the defined terminals.
When using 'auto', or requesting an unsupported terminal, we attempt to spawn
them in priority order until we get one that's available on this system (and
in the case of the X terminals, has DISPLAY defined). The 'none' value is
used when we're doing things like automated builds, and want to ensure that no
terminal is *ever* spawned, under any circumstances.
Current available terminals:
gnome
konsole
xterm
rxvt
screen
(From OE-Core rev: 69f77f80965fa06a057837f8f49eda06855c4086)
Signed-off-by: Chris Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2011-03-29 19:53:19 +00:00
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class Registry(oe.classutils.ClassRegistry):
|
|
|
|
command = None
|
|
|
|
|
|
|
|
def __init__(cls, name, bases, attrs):
|
|
|
|
super(Registry, cls).__init__(name.lower(), bases, attrs)
|
|
|
|
|
|
|
|
@property
|
|
|
|
def implemented(cls):
|
|
|
|
return bool(cls.command)
|
|
|
|
|
|
|
|
|
2016-05-20 10:57:44 +00:00
|
|
|
class Terminal(Popen, metaclass=Registry):
|
2012-09-17 22:43:50 +00:00
|
|
|
def __init__(self, sh_cmd, title=None, env=None, d=None):
|
2012-07-17 04:03:59 +00:00
|
|
|
fmt_sh_cmd = self.format_command(sh_cmd, title)
|
Rework how the devshell functions
In the new implementation, each known terminal is defined as a class in
oe.terminal, as a subclass of bb.process.Popen. terminal.bbclass wraps this
functionality, providing the metadata pieces. It obeys the OE_TERMINAL
variable, which is a 'choice' typed variable. This variable may be 'auto',
'none', or any of the names of the defined terminals.
When using 'auto', or requesting an unsupported terminal, we attempt to spawn
them in priority order until we get one that's available on this system (and
in the case of the X terminals, has DISPLAY defined). The 'none' value is
used when we're doing things like automated builds, and want to ensure that no
terminal is *ever* spawned, under any circumstances.
Current available terminals:
gnome
konsole
xterm
rxvt
screen
(From OE-Core rev: 69f77f80965fa06a057837f8f49eda06855c4086)
Signed-off-by: Chris Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2011-03-29 19:53:19 +00:00
|
|
|
try:
|
2012-07-17 04:03:59 +00:00
|
|
|
Popen.__init__(self, fmt_sh_cmd, env=env)
|
Rework how the devshell functions
In the new implementation, each known terminal is defined as a class in
oe.terminal, as a subclass of bb.process.Popen. terminal.bbclass wraps this
functionality, providing the metadata pieces. It obeys the OE_TERMINAL
variable, which is a 'choice' typed variable. This variable may be 'auto',
'none', or any of the names of the defined terminals.
When using 'auto', or requesting an unsupported terminal, we attempt to spawn
them in priority order until we get one that's available on this system (and
in the case of the X terminals, has DISPLAY defined). The 'none' value is
used when we're doing things like automated builds, and want to ensure that no
terminal is *ever* spawned, under any circumstances.
Current available terminals:
gnome
konsole
xterm
rxvt
screen
(From OE-Core rev: 69f77f80965fa06a057837f8f49eda06855c4086)
Signed-off-by: Chris Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2011-03-29 19:53:19 +00:00
|
|
|
except OSError as exc:
|
|
|
|
import errno
|
|
|
|
if exc.errno == errno.ENOENT:
|
|
|
|
raise UnsupportedTerminal(self.name)
|
|
|
|
else:
|
|
|
|
raise
|
|
|
|
|
2012-07-17 04:03:59 +00:00
|
|
|
def format_command(self, sh_cmd, title):
|
|
|
|
fmt = {'title': title or 'Terminal', 'command': sh_cmd}
|
2016-05-20 10:57:44 +00:00
|
|
|
if isinstance(self.command, str):
|
2012-07-17 04:03:59 +00:00
|
|
|
return shlex.split(self.command.format(**fmt))
|
Rework how the devshell functions
In the new implementation, each known terminal is defined as a class in
oe.terminal, as a subclass of bb.process.Popen. terminal.bbclass wraps this
functionality, providing the metadata pieces. It obeys the OE_TERMINAL
variable, which is a 'choice' typed variable. This variable may be 'auto',
'none', or any of the names of the defined terminals.
When using 'auto', or requesting an unsupported terminal, we attempt to spawn
them in priority order until we get one that's available on this system (and
in the case of the X terminals, has DISPLAY defined). The 'none' value is
used when we're doing things like automated builds, and want to ensure that no
terminal is *ever* spawned, under any circumstances.
Current available terminals:
gnome
konsole
xterm
rxvt
screen
(From OE-Core rev: 69f77f80965fa06a057837f8f49eda06855c4086)
Signed-off-by: Chris Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2011-03-29 19:53:19 +00:00
|
|
|
else:
|
2012-07-17 04:03:59 +00:00
|
|
|
return [element.format(**fmt) for element in self.command]
|
Rework how the devshell functions
In the new implementation, each known terminal is defined as a class in
oe.terminal, as a subclass of bb.process.Popen. terminal.bbclass wraps this
functionality, providing the metadata pieces. It obeys the OE_TERMINAL
variable, which is a 'choice' typed variable. This variable may be 'auto',
'none', or any of the names of the defined terminals.
When using 'auto', or requesting an unsupported terminal, we attempt to spawn
them in priority order until we get one that's available on this system (and
in the case of the X terminals, has DISPLAY defined). The 'none' value is
used when we're doing things like automated builds, and want to ensure that no
terminal is *ever* spawned, under any circumstances.
Current available terminals:
gnome
konsole
xterm
rxvt
screen
(From OE-Core rev: 69f77f80965fa06a057837f8f49eda06855c4086)
Signed-off-by: Chris Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2011-03-29 19:53:19 +00:00
|
|
|
|
|
|
|
class XTerminal(Terminal):
|
2012-09-17 22:43:50 +00:00
|
|
|
def __init__(self, sh_cmd, title=None, env=None, d=None):
|
2012-10-19 10:37:07 +00:00
|
|
|
Terminal.__init__(self, sh_cmd, title, env, d)
|
Rework how the devshell functions
In the new implementation, each known terminal is defined as a class in
oe.terminal, as a subclass of bb.process.Popen. terminal.bbclass wraps this
functionality, providing the metadata pieces. It obeys the OE_TERMINAL
variable, which is a 'choice' typed variable. This variable may be 'auto',
'none', or any of the names of the defined terminals.
When using 'auto', or requesting an unsupported terminal, we attempt to spawn
them in priority order until we get one that's available on this system (and
in the case of the X terminals, has DISPLAY defined). The 'none' value is
used when we're doing things like automated builds, and want to ensure that no
terminal is *ever* spawned, under any circumstances.
Current available terminals:
gnome
konsole
xterm
rxvt
screen
(From OE-Core rev: 69f77f80965fa06a057837f8f49eda06855c4086)
Signed-off-by: Chris Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2011-03-29 19:53:19 +00:00
|
|
|
if not os.environ.get('DISPLAY'):
|
|
|
|
raise UnsupportedTerminal(self.name)
|
|
|
|
|
|
|
|
class Gnome(XTerminal):
|
2016-07-06 16:21:59 +00:00
|
|
|
command = 'gnome-terminal -t "{title}" -x {command}'
|
Rework how the devshell functions
In the new implementation, each known terminal is defined as a class in
oe.terminal, as a subclass of bb.process.Popen. terminal.bbclass wraps this
functionality, providing the metadata pieces. It obeys the OE_TERMINAL
variable, which is a 'choice' typed variable. This variable may be 'auto',
'none', or any of the names of the defined terminals.
When using 'auto', or requesting an unsupported terminal, we attempt to spawn
them in priority order until we get one that's available on this system (and
in the case of the X terminals, has DISPLAY defined). The 'none' value is
used when we're doing things like automated builds, and want to ensure that no
terminal is *ever* spawned, under any circumstances.
Current available terminals:
gnome
konsole
xterm
rxvt
screen
(From OE-Core rev: 69f77f80965fa06a057837f8f49eda06855c4086)
Signed-off-by: Chris Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2011-03-29 19:53:19 +00:00
|
|
|
priority = 2
|
|
|
|
|
2015-02-23 19:39:41 +00:00
|
|
|
def __init__(self, sh_cmd, title=None, env=None, d=None):
|
2015-06-02 19:54:27 +00:00
|
|
|
# Recent versions of gnome-terminal does not support non-UTF8 charset:
|
|
|
|
# https://bugzilla.gnome.org/show_bug.cgi?id=732127; as a workaround,
|
|
|
|
# clearing the LC_ALL environment variable so it uses the locale.
|
|
|
|
# Once fixed on the gnome-terminal project, this should be removed.
|
|
|
|
if os.getenv('LC_ALL'): os.putenv('LC_ALL','')
|
|
|
|
|
2016-07-06 16:08:57 +00:00
|
|
|
# We need to know when the command completes but gnome-terminal gives us no way
|
|
|
|
# to do this. We therefore write the pid to a file using a "phonehome" wrapper
|
|
|
|
# script, then monitor the pid until it exits. Thanks gnome!
|
|
|
|
import tempfile
|
|
|
|
pidfile = tempfile.NamedTemporaryFile(delete = False).name
|
|
|
|
try:
|
|
|
|
sh_cmd = "oe-gnome-terminal-phonehome " + pidfile + " " + sh_cmd
|
|
|
|
XTerminal.__init__(self, sh_cmd, title, env, d)
|
|
|
|
while os.stat(pidfile).st_size <= 0:
|
|
|
|
continue
|
|
|
|
with open(pidfile, "r") as f:
|
|
|
|
pid = int(f.readline())
|
|
|
|
finally:
|
|
|
|
os.unlink(pidfile)
|
|
|
|
|
2016-08-04 22:04:26 +00:00
|
|
|
import time
|
2016-07-06 16:08:57 +00:00
|
|
|
while True:
|
|
|
|
try:
|
|
|
|
os.kill(pid, 0)
|
2016-08-04 22:04:26 +00:00
|
|
|
time.sleep(0.1)
|
2016-07-06 16:08:57 +00:00
|
|
|
except OSError:
|
|
|
|
return
|
2015-02-23 19:39:41 +00:00
|
|
|
|
2013-07-29 08:59:44 +00:00
|
|
|
class Mate(XTerminal):
|
2013-12-30 18:17:58 +00:00
|
|
|
command = 'mate-terminal -t "{title}" -x {command}'
|
2013-07-29 08:59:44 +00:00
|
|
|
priority = 2
|
|
|
|
|
2011-10-31 21:53:14 +00:00
|
|
|
class Xfce(XTerminal):
|
2014-04-17 08:13:26 +00:00
|
|
|
command = 'xfce4-terminal -T "{title}" -e "{command}"'
|
2011-10-31 21:53:14 +00:00
|
|
|
priority = 2
|
|
|
|
|
2015-01-06 14:18:54 +00:00
|
|
|
class Terminology(XTerminal):
|
|
|
|
command = 'terminology -T="{title}" -e {command}'
|
|
|
|
priority = 2
|
|
|
|
|
Rework how the devshell functions
In the new implementation, each known terminal is defined as a class in
oe.terminal, as a subclass of bb.process.Popen. terminal.bbclass wraps this
functionality, providing the metadata pieces. It obeys the OE_TERMINAL
variable, which is a 'choice' typed variable. This variable may be 'auto',
'none', or any of the names of the defined terminals.
When using 'auto', or requesting an unsupported terminal, we attempt to spawn
them in priority order until we get one that's available on this system (and
in the case of the X terminals, has DISPLAY defined). The 'none' value is
used when we're doing things like automated builds, and want to ensure that no
terminal is *ever* spawned, under any circumstances.
Current available terminals:
gnome
konsole
xterm
rxvt
screen
(From OE-Core rev: 69f77f80965fa06a057837f8f49eda06855c4086)
Signed-off-by: Chris Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2011-03-29 19:53:19 +00:00
|
|
|
class Konsole(XTerminal):
|
2016-02-12 15:06:13 +00:00
|
|
|
command = 'konsole --nofork --workdir . -p tabtitle="{title}" -e {command}'
|
Rework how the devshell functions
In the new implementation, each known terminal is defined as a class in
oe.terminal, as a subclass of bb.process.Popen. terminal.bbclass wraps this
functionality, providing the metadata pieces. It obeys the OE_TERMINAL
variable, which is a 'choice' typed variable. This variable may be 'auto',
'none', or any of the names of the defined terminals.
When using 'auto', or requesting an unsupported terminal, we attempt to spawn
them in priority order until we get one that's available on this system (and
in the case of the X terminals, has DISPLAY defined). The 'none' value is
used when we're doing things like automated builds, and want to ensure that no
terminal is *ever* spawned, under any circumstances.
Current available terminals:
gnome
konsole
xterm
rxvt
screen
(From OE-Core rev: 69f77f80965fa06a057837f8f49eda06855c4086)
Signed-off-by: Chris Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2011-03-29 19:53:19 +00:00
|
|
|
priority = 2
|
|
|
|
|
2012-09-17 22:43:50 +00:00
|
|
|
def __init__(self, sh_cmd, title=None, env=None, d=None):
|
2011-09-16 16:36:12 +00:00
|
|
|
# Check version
|
2015-02-25 11:22:24 +00:00
|
|
|
vernum = check_terminal_version("konsole")
|
2015-02-25 11:22:25 +00:00
|
|
|
if vernum and LooseVersion(vernum) < '2.0.0':
|
|
|
|
# Konsole from KDE 3.x
|
|
|
|
self.command = 'konsole -T "{title}" -e {command}'
|
2012-09-17 22:43:50 +00:00
|
|
|
XTerminal.__init__(self, sh_cmd, title, env, d)
|
2011-09-16 16:36:12 +00:00
|
|
|
|
Rework how the devshell functions
In the new implementation, each known terminal is defined as a class in
oe.terminal, as a subclass of bb.process.Popen. terminal.bbclass wraps this
functionality, providing the metadata pieces. It obeys the OE_TERMINAL
variable, which is a 'choice' typed variable. This variable may be 'auto',
'none', or any of the names of the defined terminals.
When using 'auto', or requesting an unsupported terminal, we attempt to spawn
them in priority order until we get one that's available on this system (and
in the case of the X terminals, has DISPLAY defined). The 'none' value is
used when we're doing things like automated builds, and want to ensure that no
terminal is *ever* spawned, under any circumstances.
Current available terminals:
gnome
konsole
xterm
rxvt
screen
(From OE-Core rev: 69f77f80965fa06a057837f8f49eda06855c4086)
Signed-off-by: Chris Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2011-03-29 19:53:19 +00:00
|
|
|
class XTerm(XTerminal):
|
|
|
|
command = 'xterm -T "{title}" -e {command}'
|
|
|
|
priority = 1
|
|
|
|
|
|
|
|
class Rxvt(XTerminal):
|
|
|
|
command = 'rxvt -T "{title}" -e {command}'
|
|
|
|
priority = 1
|
|
|
|
|
|
|
|
class Screen(Terminal):
|
2011-04-05 19:01:04 +00:00
|
|
|
command = 'screen -D -m -t "{title}" -S devshell {command}'
|
|
|
|
|
2012-09-17 22:43:50 +00:00
|
|
|
def __init__(self, sh_cmd, title=None, env=None, d=None):
|
2012-07-25 17:47:28 +00:00
|
|
|
s_id = "devshell_%i" % os.getpid()
|
|
|
|
self.command = "screen -D -m -t \"{title}\" -S %s {command}" % s_id
|
2012-09-17 22:43:51 +00:00
|
|
|
Terminal.__init__(self, sh_cmd, title, env, d)
|
|
|
|
msg = 'Screen started. Please connect in another terminal with ' \
|
|
|
|
'"screen -r %s"' % s_id
|
|
|
|
if (d):
|
|
|
|
bb.event.fire(bb.event.LogExecTTY(msg, "screen -r %s" % s_id,
|
|
|
|
0.5, 10), d)
|
|
|
|
else:
|
|
|
|
logger.warn(msg)
|
Rework how the devshell functions
In the new implementation, each known terminal is defined as a class in
oe.terminal, as a subclass of bb.process.Popen. terminal.bbclass wraps this
functionality, providing the metadata pieces. It obeys the OE_TERMINAL
variable, which is a 'choice' typed variable. This variable may be 'auto',
'none', or any of the names of the defined terminals.
When using 'auto', or requesting an unsupported terminal, we attempt to spawn
them in priority order until we get one that's available on this system (and
in the case of the X terminals, has DISPLAY defined). The 'none' value is
used when we're doing things like automated builds, and want to ensure that no
terminal is *ever* spawned, under any circumstances.
Current available terminals:
gnome
konsole
xterm
rxvt
screen
(From OE-Core rev: 69f77f80965fa06a057837f8f49eda06855c4086)
Signed-off-by: Chris Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2011-03-29 19:53:19 +00:00
|
|
|
|
2013-04-04 18:45:22 +00:00
|
|
|
class TmuxRunning(Terminal):
|
|
|
|
"""Open a new pane in the current running tmux window"""
|
2013-04-05 00:44:43 +00:00
|
|
|
name = 'tmux-running'
|
2013-06-30 19:51:53 +00:00
|
|
|
command = 'tmux split-window "{command}"'
|
2013-04-04 18:45:22 +00:00
|
|
|
priority = 2.75
|
|
|
|
|
2015-02-04 16:09:12 +00:00
|
|
|
def __init__(self, sh_cmd, title=None, env=None, d=None):
|
|
|
|
if not bb.utils.which(os.getenv('PATH'), 'tmux'):
|
|
|
|
raise UnsupportedTerminal('tmux is not installed')
|
|
|
|
|
|
|
|
if not os.getenv('TMUX'):
|
|
|
|
raise UnsupportedTerminal('tmux is not running')
|
|
|
|
|
|
|
|
if not check_tmux_pane_size('tmux'):
|
2015-11-06 23:25:08 +00:00
|
|
|
raise UnsupportedTerminal('tmux pane too small or tmux < 1.9 version is being used')
|
2015-02-04 16:09:12 +00:00
|
|
|
|
|
|
|
Terminal.__init__(self, sh_cmd, title, env, d)
|
|
|
|
|
|
|
|
class TmuxNewWindow(Terminal):
|
|
|
|
"""Open a new window in the current running tmux session"""
|
|
|
|
name = 'tmux-new-window'
|
|
|
|
command = 'tmux new-window -n "{title}" "{command}"'
|
|
|
|
priority = 2.70
|
|
|
|
|
2013-04-04 18:45:22 +00:00
|
|
|
def __init__(self, sh_cmd, title=None, env=None, d=None):
|
|
|
|
if not bb.utils.which(os.getenv('PATH'), 'tmux'):
|
|
|
|
raise UnsupportedTerminal('tmux is not installed')
|
|
|
|
|
|
|
|
if not os.getenv('TMUX'):
|
|
|
|
raise UnsupportedTerminal('tmux is not running')
|
|
|
|
|
|
|
|
Terminal.__init__(self, sh_cmd, title, env, d)
|
|
|
|
|
2013-04-05 00:44:43 +00:00
|
|
|
class Tmux(Terminal):
|
2013-04-04 18:45:22 +00:00
|
|
|
"""Start a new tmux session and window"""
|
2013-06-11 14:28:03 +00:00
|
|
|
command = 'tmux new -d -s devshell -n devshell "{command}"'
|
2013-04-04 18:45:22 +00:00
|
|
|
priority = 0.75
|
|
|
|
|
|
|
|
def __init__(self, sh_cmd, title=None, env=None, d=None):
|
|
|
|
if not bb.utils.which(os.getenv('PATH'), 'tmux'):
|
|
|
|
raise UnsupportedTerminal('tmux is not installed')
|
|
|
|
|
|
|
|
# TODO: consider using a 'devshell' session shared amongst all
|
|
|
|
# devshells, if it's already there, add a new window to it.
|
|
|
|
window_name = 'devshell-%i' % os.getpid()
|
|
|
|
|
2013-06-11 14:28:03 +00:00
|
|
|
self.command = 'tmux new -d -s {0} -n {0} "{{command}}"'.format(window_name)
|
2013-04-04 18:45:22 +00:00
|
|
|
Terminal.__init__(self, sh_cmd, title, env, d)
|
|
|
|
|
|
|
|
attach_cmd = 'tmux att -t {0}'.format(window_name)
|
|
|
|
msg = 'Tmux started. Please connect in another terminal with `tmux att -t {0}`'.format(window_name)
|
|
|
|
if d:
|
|
|
|
bb.event.fire(bb.event.LogExecTTY(msg, attach_cmd, 0.5, 10), d)
|
|
|
|
else:
|
|
|
|
logger.warn(msg)
|
|
|
|
|
2012-10-19 10:37:07 +00:00
|
|
|
class Custom(Terminal):
|
|
|
|
command = 'false' # This is a placeholder
|
|
|
|
priority = 3
|
|
|
|
|
|
|
|
def __init__(self, sh_cmd, title=None, env=None, d=None):
|
|
|
|
self.command = d and d.getVar('OE_TERMINAL_CUSTOMCMD', True)
|
|
|
|
if self.command:
|
|
|
|
if not '{command}' in self.command:
|
|
|
|
self.command += ' {command}'
|
|
|
|
Terminal.__init__(self, sh_cmd, title, env, d)
|
|
|
|
logger.warn('Custom terminal was started.')
|
|
|
|
else:
|
|
|
|
logger.debug(1, 'No custom terminal (OE_TERMINAL_CUSTOMCMD) set')
|
|
|
|
raise UnsupportedTerminal('OE_TERMINAL_CUSTOMCMD not set')
|
|
|
|
|
Rework how the devshell functions
In the new implementation, each known terminal is defined as a class in
oe.terminal, as a subclass of bb.process.Popen. terminal.bbclass wraps this
functionality, providing the metadata pieces. It obeys the OE_TERMINAL
variable, which is a 'choice' typed variable. This variable may be 'auto',
'none', or any of the names of the defined terminals.
When using 'auto', or requesting an unsupported terminal, we attempt to spawn
them in priority order until we get one that's available on this system (and
in the case of the X terminals, has DISPLAY defined). The 'none' value is
used when we're doing things like automated builds, and want to ensure that no
terminal is *ever* spawned, under any circumstances.
Current available terminals:
gnome
konsole
xterm
rxvt
screen
(From OE-Core rev: 69f77f80965fa06a057837f8f49eda06855c4086)
Signed-off-by: Chris Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2011-03-29 19:53:19 +00:00
|
|
|
|
|
|
|
def prioritized():
|
|
|
|
return Registry.prioritized()
|
|
|
|
|
2012-09-17 22:43:50 +00:00
|
|
|
def spawn_preferred(sh_cmd, title=None, env=None, d=None):
|
Rework how the devshell functions
In the new implementation, each known terminal is defined as a class in
oe.terminal, as a subclass of bb.process.Popen. terminal.bbclass wraps this
functionality, providing the metadata pieces. It obeys the OE_TERMINAL
variable, which is a 'choice' typed variable. This variable may be 'auto',
'none', or any of the names of the defined terminals.
When using 'auto', or requesting an unsupported terminal, we attempt to spawn
them in priority order until we get one that's available on this system (and
in the case of the X terminals, has DISPLAY defined). The 'none' value is
used when we're doing things like automated builds, and want to ensure that no
terminal is *ever* spawned, under any circumstances.
Current available terminals:
gnome
konsole
xterm
rxvt
screen
(From OE-Core rev: 69f77f80965fa06a057837f8f49eda06855c4086)
Signed-off-by: Chris Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2011-03-29 19:53:19 +00:00
|
|
|
"""Spawn the first supported terminal, by priority"""
|
|
|
|
for terminal in prioritized():
|
|
|
|
try:
|
2012-09-17 22:43:50 +00:00
|
|
|
spawn(terminal.name, sh_cmd, title, env, d)
|
Rework how the devshell functions
In the new implementation, each known terminal is defined as a class in
oe.terminal, as a subclass of bb.process.Popen. terminal.bbclass wraps this
functionality, providing the metadata pieces. It obeys the OE_TERMINAL
variable, which is a 'choice' typed variable. This variable may be 'auto',
'none', or any of the names of the defined terminals.
When using 'auto', or requesting an unsupported terminal, we attempt to spawn
them in priority order until we get one that's available on this system (and
in the case of the X terminals, has DISPLAY defined). The 'none' value is
used when we're doing things like automated builds, and want to ensure that no
terminal is *ever* spawned, under any circumstances.
Current available terminals:
gnome
konsole
xterm
rxvt
screen
(From OE-Core rev: 69f77f80965fa06a057837f8f49eda06855c4086)
Signed-off-by: Chris Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2011-03-29 19:53:19 +00:00
|
|
|
break
|
|
|
|
except UnsupportedTerminal:
|
|
|
|
continue
|
|
|
|
else:
|
|
|
|
raise NoSupportedTerminals()
|
|
|
|
|
2012-09-17 22:43:50 +00:00
|
|
|
def spawn(name, sh_cmd, title=None, env=None, d=None):
|
Rework how the devshell functions
In the new implementation, each known terminal is defined as a class in
oe.terminal, as a subclass of bb.process.Popen. terminal.bbclass wraps this
functionality, providing the metadata pieces. It obeys the OE_TERMINAL
variable, which is a 'choice' typed variable. This variable may be 'auto',
'none', or any of the names of the defined terminals.
When using 'auto', or requesting an unsupported terminal, we attempt to spawn
them in priority order until we get one that's available on this system (and
in the case of the X terminals, has DISPLAY defined). The 'none' value is
used when we're doing things like automated builds, and want to ensure that no
terminal is *ever* spawned, under any circumstances.
Current available terminals:
gnome
konsole
xterm
rxvt
screen
(From OE-Core rev: 69f77f80965fa06a057837f8f49eda06855c4086)
Signed-off-by: Chris Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2011-03-29 19:53:19 +00:00
|
|
|
"""Spawn the specified terminal, by name"""
|
|
|
|
logger.debug(1, 'Attempting to spawn terminal "%s"', name)
|
|
|
|
try:
|
|
|
|
terminal = Registry.registry[name]
|
|
|
|
except KeyError:
|
|
|
|
raise UnsupportedTerminal(name)
|
|
|
|
|
2012-09-17 22:43:50 +00:00
|
|
|
pipe = terminal(sh_cmd, title, env, d)
|
Rework how the devshell functions
In the new implementation, each known terminal is defined as a class in
oe.terminal, as a subclass of bb.process.Popen. terminal.bbclass wraps this
functionality, providing the metadata pieces. It obeys the OE_TERMINAL
variable, which is a 'choice' typed variable. This variable may be 'auto',
'none', or any of the names of the defined terminals.
When using 'auto', or requesting an unsupported terminal, we attempt to spawn
them in priority order until we get one that's available on this system (and
in the case of the X terminals, has DISPLAY defined). The 'none' value is
used when we're doing things like automated builds, and want to ensure that no
terminal is *ever* spawned, under any circumstances.
Current available terminals:
gnome
konsole
xterm
rxvt
screen
(From OE-Core rev: 69f77f80965fa06a057837f8f49eda06855c4086)
Signed-off-by: Chris Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2011-03-29 19:53:19 +00:00
|
|
|
output = pipe.communicate()[0]
|
|
|
|
if pipe.returncode != 0:
|
2012-07-17 04:03:59 +00:00
|
|
|
raise ExecutionError(sh_cmd, pipe.returncode, output)
|
2011-09-16 16:36:12 +00:00
|
|
|
|
2015-02-04 16:09:12 +00:00
|
|
|
def check_tmux_pane_size(tmux):
|
|
|
|
import subprocess as sub
|
2015-11-06 23:25:08 +00:00
|
|
|
# On older tmux versions (<1.9), return false. The reason
|
|
|
|
# is that there is no easy way to get the height of the active panel
|
|
|
|
# on current window without nested formats (available from version 1.9)
|
|
|
|
vernum = check_terminal_version("tmux")
|
|
|
|
if vernum and LooseVersion(vernum) < '1.9':
|
|
|
|
return False
|
2015-02-04 16:09:12 +00:00
|
|
|
try:
|
|
|
|
p = sub.Popen('%s list-panes -F "#{?pane_active,#{pane_height},}"' % tmux,
|
|
|
|
shell=True,stdout=sub.PIPE,stderr=sub.PIPE)
|
|
|
|
out, err = p.communicate()
|
|
|
|
size = int(out.strip())
|
|
|
|
except OSError as exc:
|
|
|
|
import errno
|
|
|
|
if exc.errno == errno.ENOENT:
|
|
|
|
return None
|
|
|
|
else:
|
|
|
|
raise
|
2015-11-06 23:25:08 +00:00
|
|
|
|
|
|
|
return size/2 >= 19
|
2015-02-04 16:09:12 +00:00
|
|
|
|
2015-02-23 19:39:41 +00:00
|
|
|
def check_terminal_version(terminalName):
|
2011-09-16 16:36:12 +00:00
|
|
|
import subprocess as sub
|
|
|
|
try:
|
2015-11-06 23:25:08 +00:00
|
|
|
cmdversion = '%s --version' % terminalName
|
|
|
|
if terminalName.startswith('tmux'):
|
|
|
|
cmdversion = '%s -V' % terminalName
|
2015-11-26 16:59:53 +00:00
|
|
|
newenv = os.environ.copy()
|
|
|
|
newenv["LANG"] = "C"
|
|
|
|
p = sub.Popen(['sh', '-c', cmdversion], stdout=sub.PIPE, stderr=sub.PIPE, env=newenv)
|
2011-09-16 16:36:12 +00:00
|
|
|
out, err = p.communicate()
|
2016-06-09 12:53:06 +00:00
|
|
|
ver_info = out.decode().rstrip().split('\n')
|
2011-09-16 16:36:12 +00:00
|
|
|
except OSError as exc:
|
|
|
|
import errno
|
|
|
|
if exc.errno == errno.ENOENT:
|
|
|
|
return None
|
|
|
|
else:
|
|
|
|
raise
|
|
|
|
vernum = None
|
|
|
|
for ver in ver_info:
|
|
|
|
if ver.startswith('Konsole'):
|
|
|
|
vernum = ver.split(' ')[-1]
|
2015-02-25 11:22:24 +00:00
|
|
|
if ver.startswith('GNOME Terminal'):
|
2015-02-23 19:39:41 +00:00
|
|
|
vernum = ver.split(' ')[-1]
|
2015-11-06 23:25:08 +00:00
|
|
|
if ver.startswith('tmux'):
|
|
|
|
vernum = ver.split()[-1]
|
2015-02-25 11:22:24 +00:00
|
|
|
return vernum
|
2011-10-31 21:53:14 +00:00
|
|
|
|
|
|
|
def distro_name():
|
|
|
|
try:
|
|
|
|
p = Popen(['lsb_release', '-i'])
|
|
|
|
out, err = p.communicate()
|
|
|
|
distro = out.split(':')[1].strip().lower()
|
|
|
|
except:
|
|
|
|
distro = "unknown"
|
|
|
|
return distro
|