9
9
import logging
10
10
import os
11
11
import re
12
- import sys
13
12
import subprocess
14
- from distutils .version import StrictVersion , LooseVersion
13
+ import sys
14
+ from distutils .version import LooseVersion
15
15
16
16
from . import exc
17
17
from ._compat import console_to_str
18
18
19
19
logger = logging .getLogger (__name__ )
20
20
21
21
22
+ #: Minimum version of tmux required to run libtmux
23
+ TMUX_MIN_VERSION = '1.8'
24
+
25
+ #: Most recent version of tmux supported
26
+ TMUX_MAX_VERSION = '2.4'
27
+
28
+
22
29
class EnvironmentMixin (object ):
23
30
24
31
"""Mixin class for managing session and server level environment
@@ -274,8 +281,8 @@ class TmuxRelationalObject(object):
274
281
Object .children method
275
282
================ ========================= =================================
276
283
:class:`Server` :attr:`Server._sessions` :meth:`Server.list_sessions`
277
- :class:`Session` :attr:`Sessions ._windows` :meth:`Session.list_windows`
278
- :class:`Window` :attr:`Windows ._panes` :meth:`Window.list_panes`
284
+ :class:`Session` :attr:`Session ._windows` :meth:`Session.list_windows`
285
+ :class:`Window` :attr:`Window ._panes` :meth:`Window.list_panes`
279
286
:class:`Pane` n/a n/a
280
287
================ ========================= =================================
281
288
@@ -395,67 +402,122 @@ def _is_executable_file_or_link(exe):
395
402
return None
396
403
397
404
398
- def is_version (version ):
405
+ def get_version ():
406
+ """Return tmux version.
407
+
408
+ If tmux is built from git master, the version returned will be the latest
409
+ version appended with -master, e.g. ``2.4-master``.
410
+
411
+ If using OpenBSD's base system tmux, the version will have ``-openbsd``
412
+ appended to the latest version, e.g. ``2.4-openbsd``.
413
+
414
+ :returns: tmux version
415
+ :rtype: :class:`distutils.version.LooseVersion`
416
+ """
417
+ proc = tmux_cmd ('-V' )
418
+ if proc .stderr :
419
+ if proc .stderr [0 ] == 'tmux: unknown option -- V' :
420
+ if sys .platform .startswith ("openbsd" ): # openbsd has no tmux -V
421
+ return LooseVersion ('%s-openbsd' % TMUX_MAX_VERSION )
422
+ raise exc .LibTmuxException (
423
+ 'libtmux supports tmux %s and greater. This system'
424
+ ' is running tmux 1.3 or earlier.' % TMUX_MIN_VERSION
425
+ )
426
+ raise exc .VersionTooLow (proc .stderr )
427
+
428
+ version = proc .stdout [0 ].split ('tmux ' )[1 ]
429
+
430
+ # Allow latest tmux HEAD
431
+ if version == 'master' :
432
+ return LooseVersion ('%s-master' % TMUX_MAX_VERSION )
433
+
434
+ version = re .sub (r'[a-z]' , '' , version )
435
+
436
+ return LooseVersion (version )
437
+
438
+
439
+ def has_version (version ):
399
440
"""Return True if tmux version installed.
400
441
401
442
:param version: version, '1.8'
402
- :param type: string
443
+ :type version: string
444
+ :returns: True if version matches
403
445
:rtype: bool
446
+ """
447
+ return get_version () == LooseVersion (version )
448
+
404
449
450
+ def has_gt_version (min_version ):
451
+ """Return True if tmux version greater than minimum.
452
+
453
+ :param min_version: version, e.g. '1.8'
454
+ :type min_version: string
455
+ :returns: True if version above min_version
456
+ :rtype: bool
405
457
"""
406
- if sys .platform .startswith ("openbsd" ):
407
- if LooseVersion (version ) > LooseVersion ('2.1' ):
408
- return 'openbsd'
409
- else :
410
- return False
458
+ return get_version () > LooseVersion (min_version )
411
459
412
- proc = tmux_cmd ('-V' )
413
460
414
- if proc . stderr :
415
- raise exc . LibTmuxException ( proc . stderr )
461
+ def has_gte_version ( min_version ) :
462
+ """Return True if tmux version greater or equal to minimum.
416
463
417
- installed_version = proc .stdout [0 ].split ('tmux ' )[1 ]
464
+ :param min_version: version, e.g. '1.8'
465
+ :type min_version: string
466
+ :returns: True if version above or equal to min_version
467
+ :rtype: bool
468
+ """
469
+ return get_version () >= LooseVersion (min_version )
418
470
419
- return LooseVersion (installed_version ) == LooseVersion (version )
420
471
472
+ def has_lte_version (max_version ):
473
+ """Return True if tmux version less or equal to minimum.
421
474
422
- def has_required_tmux_version (version = None ):
423
- """Return if tmux meets version requirement. Version >1.8 or above.
475
+ :param max_version: version, e.g. '1.8'
476
+ :type max_version: string
477
+ :returns: True if version below or equal to max_version
478
+ :rtype: bool
479
+ """
480
+ return get_version () <= LooseVersion (max_version )
424
481
425
- :versionchanged: 0.1.7
426
- Versions will now remove trailing letters per `Issue 55`_.
427
482
428
- .. _Issue 55: https://github.com/tony/tmuxp/issues/55.
483
+ def has_lt_version (max_version ):
484
+ """Return True if tmux version less than minimum.
429
485
486
+ :param max_version: version, e.g. '1.8'
487
+ :type max_version: string
488
+ :returns: True if version below max_version
489
+ :rtype: bool
430
490
"""
491
+ return get_version () < LooseVersion (max_version )
431
492
432
- if not version :
433
- if sys .platform .startswith ("openbsd" ): # openbsd has no tmux -V
434
- return '2.3'
435
493
436
- proc = tmux_cmd ('-V' )
494
+ def has_minimum_version (raises = True ):
495
+ """Return if tmux meets version requirement. Version >1.8 or above.
437
496
438
- if proc .stderr :
439
- if proc .stderr [0 ] == 'tmux: unknown option -- V' :
440
- raise exc .LibTmuxException (
441
- 'libtmux supports tmux 1.8 and greater. This system'
442
- ' is running tmux 1.3 or earlier.' )
443
- raise exc .LibTmuxException (proc .stderr )
497
+ :param raises: Will raise exception if version too low, default ``True``
498
+ :type raises: bool
499
+ :returns: True if tmux meets minimum required version
500
+ :rtype: bool
444
501
445
- version = proc .stdout [0 ].split ('tmux ' )[1 ]
502
+ :versionchanged: 0.7.0
503
+ No longer returns version, returns True or False
504
+ :versionchanged: 0.1.7
505
+ Versions will now remove trailing letters per `Issue 55`_.
446
506
447
- # Allow latest tmux HEAD
448
- if version == 'master' :
449
- return version
507
+ .. _Issue 55: https://github.com/tony/tmuxp/issues/55.
450
508
451
- version = re . sub ( r'[a-z]' , '' , version )
509
+ """
452
510
453
- if StrictVersion (version ) <= StrictVersion ("1.7" ):
454
- raise exc .LibTmuxException (
455
- 'libtmux only supports tmux 1.8 and greater. This system'
456
- ' has %s installed. Upgrade your tmux to use libtmux.' % version
457
- )
458
- return version
511
+ if get_version () < LooseVersion (TMUX_MIN_VERSION ):
512
+ if raises :
513
+ raise exc .VersionTooLow (
514
+ 'libtmux only supports tmux %s and greater. This system'
515
+ ' has %s installed. Upgrade your tmux to use libtmux.' %
516
+ (TMUX_MIN_VERSION , get_version ())
517
+ )
518
+ else :
519
+ return False
520
+ return True
459
521
460
522
461
523
def session_check_name (session_name ):
@@ -477,3 +539,32 @@ def session_check_name(session_name):
477
539
elif ':' in session_name :
478
540
raise exc .BadSessionName (
479
541
"tmux session name \" %s\" may not contain colons." , session_name )
542
+
543
+
544
+ def handle_option_error (error ):
545
+ """Raises exception if error in option command found.
546
+
547
+ Purpose: As of tmux 2.4, there are now 3 different types of option errors:
548
+
549
+ - unknown option
550
+ - invalid option
551
+ - ambiguous option
552
+
553
+ Before 2.4, unknown option was the user.
554
+
555
+ All errors raised will have the base error of :exc:`exc.OptionError`. So to
556
+ catch any option error, use ``except exc.OptionError``.
557
+
558
+ :param error: error response from subprocess call
559
+ :type error: str
560
+ :raises: :exc:`exc.OptionError`, :exc:`exc.UnknownOption`,
561
+ :exc:`exc.InvalidOption`, :exc:`excAmbiguousOption`
562
+ """
563
+ if 'unknown option' in error :
564
+ raise exc .UnknownOption (error )
565
+ elif 'invalid option' in error :
566
+ raise exc .InvalidOption (error )
567
+ elif 'ambiguous option' in error :
568
+ raise exc .AmbiguousOption (error )
569
+ else :
570
+ raise exc .OptionError (error ) # Raise generic option error
0 commit comments