Skip to content

Commit d2871a3

Browse files
committed
Add channel filtering in Charmhub.info
1 parent 7593328 commit d2871a3

1 file changed

Lines changed: 31 additions & 11 deletions

File tree

juju/charmhub.py

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,30 +64,35 @@ async def info(self, name, channel=None):
6464
if not name:
6565
raise JujuError("name expected")
6666

67-
if channel is None:
68-
channel = ""
69-
7067
if self.model.connection().is_using_old_client:
68+
if channel is None:
69+
channel = ""
7170
facade = self._facade()
72-
res = await facade.Info(tag="application-{}".format(name), channel=channel)
71+
res = await facade.Info(tag="application-{}".format(name),
72+
channel=channel)
7373
err_code = res.errors.error_list.code
7474
if err_code:
75-
raise JujuError(f'charmhub.info - {err_code} : {res.errors.error_list.message}')
75+
raise JujuError(f'charmhub.info - {err_code} :'
76+
f' {res.errors.error_list.message}')
7677
result = res.result
7778
result.channel_map = CharmHub._channel_map_to_dict(
78-
result.channel_map)
79+
result.channel_map,
80+
name,
81+
channel=channel)
7982
result = result.serialize()
8083
else:
8184
charmhub_url = await self._charmhub_url()
8285
url = "{}/v2/charms/info/{}?fields=channel-map".format(
8386
charmhub_url.value, name)
8487
_response = self.request_charmhub_with_retry(url, 5)
8588
result = json.loads(_response.text)
86-
result['channel-map'] = CharmHub._channel_list_to_map(result['channel-map'])
89+
result['channel-map'] = CharmHub._channel_list_to_map(result['channel-map'],
90+
name,
91+
channel=channel)
8792
return result
8893

8994
@staticmethod
90-
def _channel_list_to_map(channel_list_map):
95+
def _channel_list_to_map(channel_list_map, name, channel=""):
9196
"""Charmhub API returns the channel map as a list of channel objects
9297
(with risk, track, revision, download etc). This turns that into a map
9398
that's keyed with the channel=track/risk for easy
@@ -105,12 +110,22 @@ def _channel_list_to_map(channel_list_map):
105110
"""
106111
channel_map = {}
107112
for ch in channel_list_map:
108-
channel_map[f"{ch['channel']['track']}/{ch['channel']['risk']}"] \
109-
= ch
113+
ch_name = f"{ch['channel']['track']}/{ch['channel']['risk']}"
114+
if channel and channel != ch_name:
115+
# If channel is given, then filter out the rest
116+
continue
117+
channel_map[ch_name] = ch
118+
if channel == ch_name:
119+
# If we found the desired channel, no need to continue
120+
break
121+
# After loop is done, check for non-existent channel
122+
if channel and channel not in channel_map:
123+
raise JujuError(f'Charmhub.info : channel {channel} not found for'
124+
f' {name}')
110125
return channel_map
111126

112127
@staticmethod
113-
def _channel_map_to_dict(channel_map):
128+
def _channel_map_to_dict(channel_map, name, channel=""):
114129
"""Converts the client.definitions.Channel objects into python maps
115130
inside a channel map (for pylibjuju <3.0)
116131
@@ -119,9 +134,14 @@ def _channel_map_to_dict(channel_map):
119134
"""
120135
channel_dict = {}
121136
for ch_name, ch_obj in channel_map.items():
137+
# No need to worry about filtering channel
138+
# Charmhub facade will take care of that
122139
_ch = ch_obj.serialize()
123140
_ch['platforms'] = [p.serialize() for p in _ch['platforms']]
124141
channel_dict[ch_name] = _ch
142+
if channel and channel not in channel_dict:
143+
raise JujuError(f'Charmhub.info : channel {channel} not found for'
144+
f' {name}')
125145
return channel_dict
126146

127147
async def find(self, query, category=None, channel=None,

0 commit comments

Comments
 (0)