Skip to content

Commit 8ad2d1e

Browse files
committed
Allow users to show, download and apply bundles by name
This was another ask from my colleague. As noted in the code, this is done in the client as the functionality doesn't really make sense in the server. Signed-off-by: Stephen Finucane <stephen@that.guru>
1 parent fa76b52 commit 8ad2d1e

File tree

3 files changed

+48
-11
lines changed

3 files changed

+48
-11
lines changed

git_pw/api.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,13 @@ def download(url, params=None):
150150
rsp = get(url, params, stream=True)
151151

152152
# we don't catch anything here because we should break if these are missing
153-
header = rsp.headers['content-disposition']
154-
output_path = re.search('filename=(.+)', header).group(1)
153+
header = re.search('filename=(.+)',
154+
rsp.headers.get('content-disposition') or '')
155+
if not header:
156+
LOG.error('Filename was expected but was not provided in response')
157+
sys.exit(1)
158+
159+
output_path = header.group(1)
155160

156161
with open(output_path, 'wb') as output_file:
157162
LOG.debug('Saving to %s', output_path)

git_pw/bundle.py

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,45 @@
1414
LOG = logging.getLogger(__name__)
1515

1616

17+
def _get_bundle(bundle_id):
18+
"""Fetch bundle by ID or name.
19+
20+
Allow users to provide a string to search for bundles. This doesn't make
21+
sense to expose via the API since there's no uniqueness constraint on
22+
bundle names.
23+
"""
24+
if bundle_id.isdigit():
25+
return api.detail('bundles', bundle_id)
26+
27+
bundles = api.index('bundles', [('q', bundle_id)])
28+
if len(bundles) == 0:
29+
LOG.error('No matching bundle found: %s', bundle_id)
30+
sys.exit(1)
31+
elif len(bundles) > 1:
32+
LOG.error('More than one bundle found: %s', bundle_id)
33+
sys.exit(1)
34+
35+
return bundles[0]
36+
37+
1738
@click.command(name='apply')
18-
@click.argument('bundle_id', type=click.INT)
39+
@click.argument('bundle_id')
1940
@click.argument('args', nargs=-1)
2041
def apply_cmd(bundle_id, args):
2142
"""Apply bundle.
2243
2344
Apply a bundle locally using the 'git-am' command.
2445
"""
25-
LOG.debug('Applying bundle: id=%d', bundle_id)
46+
LOG.debug('Applying bundle: id=%s', bundle_id)
2647

27-
bundle = api.detail('bundles', bundle_id)
48+
bundle = _get_bundle(bundle_id)
2849
mbox = api.download(bundle['mbox']).text
2950

3051
utils.git_am(mbox, args)
3152

3253

3354
@click.command(name='download')
34-
@click.argument('bundle_id', type=click.INT)
55+
@click.argument('bundle_id')
3556
@click.argument('output', type=click.File('wb'), required=False)
3657
def download_cmd(bundle_id, output):
3758
"""Download bundle in mbox format.
@@ -40,10 +61,10 @@ def download_cmd(bundle_id, output):
4061
output path or ``-`` to output to ``stdout``. If ``OUTPUT`` is not
4162
provided, the output path will be automatically chosen.
4263
"""
43-
LOG.debug('Downloading bundle: id=%d', bundle_id)
64+
LOG.debug('Downloading bundle: id=%s', bundle_id)
4465

4566
path = None
46-
bundle = api.detail('bundles', bundle_id)
67+
bundle = _get_bundle(bundle_id)
4768

4869
if output:
4970
output.write(api.get(bundle['mbox']).text)
@@ -58,15 +79,15 @@ def download_cmd(bundle_id, output):
5879

5980

6081
@click.command(name='show')
61-
@click.argument('bundle_id', type=click.INT)
82+
@click.argument('bundle_id')
6283
def show_cmd(bundle_id):
6384
"""Show information about bundle.
6485
6586
Retrieve Patchwork metadata for a bundle.
6687
"""
67-
LOG.debug('Showing bundle: id=%d', bundle_id)
88+
LOG.debug('Showing bundle: id=%s', bundle_id)
6889

69-
bundle = api.detail('bundles', bundle_id)
90+
bundle = _get_bundle(bundle_id)
7091

7192
def _format_patch(patch):
7293
return '%-4d %s' % (patch.get('id'), patch.get('name'))
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
features:
3+
- |
4+
It's now possible to use a bundle name in addition to the numeric ID for
5+
the ``bundle download``, ``bundle apply`` and ``bundle show`` commands.
6+
For example::
7+
8+
$ git pw bundle show 'My sample bundle'
9+
10+
As bundle names are not necessarily unique, this will fail if multiple
11+
bundles match the provided string.

0 commit comments

Comments
 (0)