12
12
13
13
import json
14
14
import re
15
+ import warnings
15
16
16
- from testinfra .modules .base import InstanceModule
17
+ from testinfra .modules .base import Module
17
18
18
19
19
20
def _re_match (line , regexp ):
@@ -23,10 +24,38 @@ def _re_match(line, regexp):
23
24
return match .groups ()
24
25
25
26
26
- class PipPackage ( InstanceModule ):
27
- """Test pip packages status and version """
27
+ class Pip ( Module ):
28
+ """Test pip package manager and packages """
28
29
29
- def check (self , pip_path = "pip" ):
30
+ def __init__ (self , name , pip_path = "pip" ):
31
+ self .name = name
32
+ self .pip_path = pip_path
33
+ super ().__init__ ()
34
+
35
+ @property
36
+ def is_installed (self ):
37
+ """Test if the package is installed
38
+
39
+ >>> host.package("pip").is_installed
40
+ True
41
+ """
42
+ return self .run_test ("%s show %s" , self .pip_path , self .name ).rc == 0
43
+
44
+ @property
45
+ def version (self ):
46
+ """Return package version as returned by pip
47
+
48
+ >>> host.package("pip").version
49
+ '18.1'
50
+ """
51
+ return self .check_output (
52
+ "%s show %s | grep Version: | cut -d' ' -f2" ,
53
+ self .pip_path ,
54
+ self .name ,
55
+ )
56
+
57
+ @classmethod
58
+ def check (cls , pip_path = "pip" ):
30
59
"""Verify installed packages have compatible dependencies.
31
60
32
61
>>> cmd = host.pip_package.check()
@@ -41,20 +70,18 @@ def check(self, pip_path="pip"):
41
70
.. _pip check: https://pip.pypa.io/en/stable/reference/pip_check/
42
71
.. _9.0.0: https://pip.pypa.io/en/stable/news/#id526
43
72
"""
44
- cmd = "{} check" .format (pip_path )
45
- return self .run_expect ([0 , 1 ], cmd )
73
+ return cls .run_expect ([0 , 1 ], "%s check" , pip_path )
46
74
47
- def get_packages (self , pip_path = "pip" ):
75
+ @classmethod
76
+ def get_packages (cls , pip_path = "pip" ):
48
77
"""Get all installed packages and versions returned by `pip list`:
49
78
50
79
>>> host.pip_package.get_packages(pip_path='~/venv/website/bin/pip')
51
80
{'Django': {'version': '1.10.2'},
52
81
'mywebsite': {'version': '1.0a3', 'path': '/srv/website'},
53
82
'psycopg2': {'version': '2.6.2'}}
54
83
"""
55
- out = self .run_expect (
56
- [0 , 2 ], "{0} list --no-index --format=json" .format (pip_path )
57
- )
84
+ out = cls .run_expect ([0 , 2 ], "%s list --no-index --format=json" , pip_path )
58
85
pkgs = {}
59
86
if out .rc == 0 :
60
87
for pkg in json .loads (out .stdout ):
@@ -63,9 +90,7 @@ def get_packages(self, pip_path="pip"):
63
90
else :
64
91
# pip < 9
65
92
output_re = re .compile (r"^(.+) \((.+)\)$" )
66
- for line in self .check_output (
67
- "{0} list --no-index" .format (pip_path )
68
- ).splitlines ():
93
+ for line in cls .check_output ("%s list --no-index" , pip_path ).splitlines ():
69
94
if line .startswith ("Warning: " ):
70
95
# Warning: cannot find svn location for ...
71
96
continue
@@ -77,14 +102,15 @@ def get_packages(self, pip_path="pip"):
77
102
pkgs [name ] = {"version" : version }
78
103
return pkgs
79
104
80
- def get_outdated_packages (self , pip_path = "pip" ):
105
+ @classmethod
106
+ def get_outdated_packages (cls , pip_path = "pip" ):
81
107
"""Get all outdated packages with current and latest version
82
108
83
109
>>> host.pip_package.get_outdated_packages(
84
110
... pip_path='~/venv/website/bin/pip')
85
111
{'Django': {'current': '1.10.2', 'latest': '1.10.3'}}
86
112
"""
87
- out = self .run_expect ([0 , 2 ], "{0} list -o --format=json" . format ( pip_path ) )
113
+ out = cls .run_expect ([0 , 2 ], "%s list -o --format=json" , pip_path )
88
114
pkgs = {}
89
115
if out .rc == 0 :
90
116
for pkg in json .loads (out .stdout ):
@@ -100,11 +126,41 @@ def get_outdated_packages(self, pip_path="pip"):
100
126
re .compile (r"^(.+?) \((.+)\) - Latest: (.+) .*$" ),
101
127
re .compile (r"^(.+?) \(Current: (.+) Latest: (.+) .*$" ),
102
128
]
103
- for line in self .check_output ("{0} list -o" . format ( pip_path ) ).splitlines ():
129
+ for line in cls .check_output ("%s list -o" , pip_path ).splitlines ():
104
130
if line .startswith ("Warning: " ):
105
131
# Warning: cannot find svn location for ...
106
132
continue
107
133
output_re = regexpes [1 ] if "Current:" in line else regexpes [0 ]
108
134
name , current , latest = _re_match (line , output_re )
109
135
pkgs [name ] = {"current" : current , "latest" : latest }
110
136
return pkgs
137
+
138
+
139
+ class PipPackage (Pip ):
140
+ """.. deprecated:: 6.2
141
+
142
+ Use :class:`~testinfra.modules.pip.Pip` instead.
143
+ """
144
+
145
+ @staticmethod
146
+ def _deprecated ():
147
+ """Raise a `DeprecationWarning`"""
148
+ warnings .warn (
149
+ "Calling host.pip_package is deprecated, call host.pip instead" ,
150
+ DeprecationWarning ,
151
+ )
152
+
153
+ @classmethod
154
+ def check (cls , pip_path = "pip" ):
155
+ PipPackage ._deprecated ()
156
+ return super ().check (pip_path = pip_path )
157
+
158
+ @classmethod
159
+ def get_packages (cls , pip_path = "pip" ):
160
+ PipPackage ._deprecated ()
161
+ return super ().get_packages (pip_path = pip_path )
162
+
163
+ @classmethod
164
+ def get_outdated_packages (cls , pip_path = "pip" ):
165
+ PipPackage ._deprecated ()
166
+ return super ().get_outdated_packages (pip_path = pip_path )
0 commit comments