Skip to content

Commit a93cc3f

Browse files
author
Dean Troyer
committed
Add module list command
Lists versions of installed python modules (Origianlly proposed as 'version list') Change-Id: I76a51d3d6783f46ef2daa0a41626019a880a2a50
1 parent d45187a commit a93cc3f

4 files changed

Lines changed: 155 additions & 0 deletions

File tree

openstackclient/common/module.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Copyright 2013 Nebula Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
4+
# not use this file except in compliance with the License. You may obtain
5+
# a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations
13+
# under the License.
14+
#
15+
16+
"""Module action implementation"""
17+
18+
import logging
19+
import six
20+
import sys
21+
22+
from cliff import show
23+
24+
25+
class ListModule(show.ShowOne):
26+
"""List module versions"""
27+
28+
auth_required = False
29+
log = logging.getLogger(__name__ + '.ListModule')
30+
31+
def get_parser(self, prog_name):
32+
parser = super(ListModule, self).get_parser(prog_name)
33+
parser.add_argument(
34+
'--all',
35+
action='store_true',
36+
default=False,
37+
help='Show all modules that have version information',
38+
)
39+
return parser
40+
41+
def take_action(self, parsed_args):
42+
self.log.debug('take_action(%s)' % parsed_args)
43+
44+
data = {}
45+
# Get module versions
46+
mods = sys.modules
47+
for k in mods.keys():
48+
k = k.split('.')[0]
49+
# TODO(dtroyer): Need a better way to decide which modules to
50+
# show for the default (not --all) invocation.
51+
# It should be just the things we actually care
52+
# about like client and plugin modules...
53+
if (parsed_args.all or 'client' in k):
54+
try:
55+
data[k] = mods[k].__version__
56+
except AttributeError:
57+
# aw, just skip it
58+
pass
59+
60+
return zip(*sorted(six.iteritems(data)))
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Copyright 2013 Nebula Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
4+
# not use this file except in compliance with the License. You may obtain
5+
# a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations
13+
# under the License.
14+
#
15+
16+
"""Test module module"""
17+
18+
import mock
19+
20+
from openstackclient.common import module as osc_module
21+
from openstackclient.tests import fakes
22+
from openstackclient.tests import utils
23+
24+
25+
# NOTE(dtroyer): module_1 must match the version list filter (not --all)
26+
# currently == '*client*'
27+
module_name_1 = 'fakeclient'
28+
module_version_1 = '0.1.2'
29+
MODULE_1 = {
30+
'__version__': module_version_1,
31+
}
32+
33+
module_name_2 = 'zlib'
34+
module_version_2 = '1.1'
35+
MODULE_2 = {
36+
'__version__': module_version_2,
37+
}
38+
39+
MODULES = {
40+
module_name_1: fakes.FakeModule(module_name_1, module_version_1),
41+
module_name_2: fakes.FakeModule(module_name_2, module_version_2),
42+
}
43+
44+
45+
@mock.patch.dict(
46+
'openstackclient.common.module.sys.modules',
47+
values=MODULES,
48+
clear=True,
49+
)
50+
class TestModuleList(utils.TestCommand):
51+
52+
def setUp(self):
53+
super(TestModuleList, self).setUp()
54+
55+
# Get the command object to test
56+
self.cmd = osc_module.ListModule(self.app, None)
57+
58+
def test_module_list_no_options(self):
59+
arglist = []
60+
verifylist = [
61+
('all', False),
62+
]
63+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
64+
65+
# DisplayCommandBase.take_action() returns two tuples
66+
columns, data = self.cmd.take_action(parsed_args)
67+
68+
# Additional modules may be present, just check our additions
69+
self.assertTrue(module_name_1 in columns)
70+
self.assertTrue(module_version_1 in data)
71+
72+
def test_module_list_all(self):
73+
arglist = [
74+
'--all',
75+
]
76+
verifylist = [
77+
('all', True),
78+
]
79+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
80+
81+
# DisplayCommandBase.take_action() returns two tuples
82+
columns, data = self.cmd.take_action(parsed_args)
83+
84+
# Additional modules may be present, just check our additions
85+
self.assertTrue(module_name_1 in columns)
86+
self.assertTrue(module_name_2 in columns)
87+
self.assertTrue(module_version_1 in data)
88+
self.assertTrue(module_version_2 in data)

openstackclient/tests/fakes.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ def __init__(self):
5353
self.auth_ref = None
5454

5555

56+
class FakeModule(object):
57+
def __init__(self, name, version):
58+
self.name = name
59+
self.__version__ = version
60+
61+
5662
class FakeResource(object):
5763
def __init__(self, manager, info, loaded=False):
5864
self.manager = manager

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ console_scripts =
2626
openstack = openstackclient.shell:main
2727

2828
openstack.cli =
29+
module_list = openstackclient.common.module:ListModule
2930

3031
openstack.common =
3132
limits_show = openstackclient.common.limits:ShowLimits

0 commit comments

Comments
 (0)