Hello community, here is the log from the commit of package python-git-pw for openSUSE:Factory checked in at 2020-06-24 15:49:31 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-git-pw (Old) and /work/SRC/openSUSE:Factory/.python-git-pw.new.2956 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-git-pw" Wed Jun 24 15:49:31 2020 rev:2 rq:816755 version:1.9.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-git-pw/python-git-pw.changes 2020-04-01 19:12:19.115368612 +0200 +++ /work/SRC/openSUSE:Factory/.python-git-pw.new.2956/python-git-pw.changes 2020-06-24 15:49:34.592578647 +0200 @@ -1,0 +2,11 @@ +Wed Jun 24 04:27:25 UTC 2020 - Steve Kowalik <[email protected]> + +- Update to 1.9.0: + * Adds support for Patchwork API v1.2 and introduces five new commands: + + bundle create + + bundle update + + bundle delete + + bundle add + + bundle remove + +------------------------------------------------------------------- Old: ---- git-pw-1.8.1.tar.gz New: ---- git-pw-1.9.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-git-pw.spec ++++++ --- /var/tmp/diff_new_pack.taUyBw/_old 2020-06-24 15:49:35.228581312 +0200 +++ /var/tmp/diff_new_pack.taUyBw/_new 2020-06-24 15:49:35.232581330 +0200 @@ -19,7 +19,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %define modname git-pw Name: python-git-pw -Version: 1.8.1 +Version: 1.9.0 Release: 0 Summary: A tool for integrating Git with Patchwork License: MIT ++++++ git-pw-1.8.1.tar.gz -> git-pw-1.9.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/AUTHORS new/git-pw-1.9.0/AUTHORS --- old/git-pw-1.8.1/AUTHORS 2020-03-31 18:06:45.000000000 +0200 +++ new/git-pw-1.9.0/AUTHORS 2020-04-18 01:10:02.000000000 +0200 @@ -1,4 +1,3 @@ Ezequiel Garcia <[email protected]> Michael Ellerman <[email protected]> Stephen Finucane <[email protected]> -Tom Tromey <[email protected]> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/ChangeLog new/git-pw-1.9.0/ChangeLog --- old/git-pw-1.8.1/ChangeLog 2020-03-31 18:06:45.000000000 +0200 +++ new/git-pw-1.9.0/ChangeLog 2020-04-18 01:10:02.000000000 +0200 @@ -1,6 +1,19 @@ CHANGES ======= +1.9.0 +----- + +* docs: Highlight the impending removal of Python 2.7 +* docs: Update requirements +* man: Update man pages to reflect latest changes +* Add 'bundle add', 'bundle remove' commands +* Add 'bundle delete' command +* Add 'bundle update' command +* Add 'bundle create' command +* Improve API of 'git\_pw.api' module +* tox: Update click-man version + 1.8.1 ----- @@ -69,16 +82,3 @@ * Add support for multiple output formats * Handle bytestring decode in 'git\_config' helper * requirements: Make requirements less strict -* docs: Remove unnecessary settings from 'conf.py' -* api: Rename 'put' -> 'patch' -* Revert "travis: Start testing Python 3.7, PyPy" -* travis: Use travis to publish packages -* travis: Start testing Python 3.7, PyPy - -1.4.0 ------ - -* Don't exit if multiple matches found for a filter -* Add support for filtering by user/submitter ID -* Re-add support for filtering by submitter name, user email -* Fix a simple typo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/PKG-INFO new/git-pw-1.9.0/PKG-INFO --- old/git-pw-1.8.1/PKG-INFO 2020-03-31 18:06:45.756854800 +0200 +++ new/git-pw-1.9.0/PKG-INFO 2020-04-18 01:10:02.455363300 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.2 Name: git-pw -Version: 1.8.1 +Version: 1.9.0 Summary: Git-Patchwork integration tool Home-page: https://github.com/getpatchwork/git-pw Author: Stephen Finucane diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/docs/requirements.txt new/git-pw-1.9.0/docs/requirements.txt --- old/git-pw-1.8.1/docs/requirements.txt 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/docs/requirements.txt 2020-04-18 01:09:43.000000000 +0200 @@ -1,5 +1,5 @@ -r ../requirements.txt sphinx>=1.5,<2.0 -sphinx-click>=1.0,<2.0 -reno>=2.0,<3.0 -sphinx_rtd_theme==0.3.1 +sphinx-click>=2.0,<3.0 +reno>=3.0,<4.0 +sphinx-rtd-theme==0.4.3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/git_pw/api.py new/git-pw-1.9.0/git_pw/api.py --- old/git-pw-1.8.1/git_pw/api.py 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/git_pw/api.py 2020-04-18 01:09:43.000000000 +0200 @@ -6,6 +6,7 @@ import logging import os.path import re +import pty import sys import tempfile @@ -16,10 +17,14 @@ from git_pw import config if 0: # noqa + from typing import Any # noqa + from typing import Callable # noqa from typing import Dict # noqa + from typing import IO # noqa from typing import List # noqa from typing import Optional # noqa from typing import Tuple # noqa + from typing import Union # noqa Filters = List[Tuple[str, str]] @@ -121,20 +126,7 @@ sys.exit(1) -def version(): - # type: () -> Optional[Tuple[int, int]] - """Get the version of the server from the URL, if present.""" - server = _get_server() - - version = re.match(r'.*/(\d)\.(\d)$', server) - if version: - return (int(version.group(1)), int(version.group(2))) - - # return the oldest version we support if no version provided - return (1, 0) - - -def get(url, params=None, stream=False): +def _get(url, params=None, stream=False): # type: (str, Filters, bool) -> requests.Response """Make GET request and handle errors.""" LOG.debug('GET %s', url) @@ -155,7 +147,24 @@ return rsp -def patch(url, data): +def _post(url, data): + # type: (str, dict) -> requests.Response + """Make POST request and handle errors.""" + LOG.debug('POST %s, data=%r', url, data) + + try: + rsp = requests.post(url, auth=_get_auth(), headers=_get_headers(), + data=data) + rsp.raise_for_status() + except requests.exceptions.RequestException as exc: + _handle_error('create', exc) + + LOG.debug('Got response') + + return rsp + + +def _patch(url, data): # type: (str, dict) -> requests.Response """Make PATCH request and handle errors.""" LOG.debug('PATCH %s, data=%r', url, data) @@ -172,39 +181,80 @@ return rsp -def download(url, params=None): - # type: (str, Filters) -> str - """Retrieve a specific API resource and save it to a file. +def _delete(url): + # type: (str) -> requests.Response + """Make DELETE request and handle errors.""" + LOG.debug('DELETE %s', url) - GET /{resource}/{resourceID}/ + try: + rsp = requests.delete(url, auth=_get_auth(), headers=_get_headers()) + rsp.raise_for_status() + except requests.exceptions.RequestException as exc: + _handle_error('delete', exc) + + LOG.debug('Got response') + + return rsp + + +def version(): + # type: () -> Optional[Tuple[int, int]] + """Get the version of the server from the URL, if present.""" + server = _get_server() + + version = re.match(r'.*/(\d)\.(\d)$', server) + if version: + return (int(version.group(1)), int(version.group(2))) + + # return the oldest version we support if no version provided + return (1, 0) + + +def download(url, params=None, output=None): + # type: (str, Filters, IO) -> Optional[str] + """Retrieve a specific API resource and save it to a file/stdout. The ``Content-Disposition`` header is assumed to be present and - will be used for the output filename. + will be used for the output filename, if not writing to stdout. Arguments: url: The resource URL. params: Additional parameters. + output: The output file. If provided, the caller is responsible for + closing. If None, a temporary file will be used. Returns: - A path to an output file containing the content. + A path to an output file containing the content, else None if stdout + used. """ - rsp = get(url, params, stream=True) + rsp = _get(url, params, stream=True) # we don't catch anything here because we should break if these are missing - header = re.search('filename=(.+)', - rsp.headers.get('content-disposition') or '') + header = re.search( + 'filename=(.+)', rsp.headers.get('content-disposition') or '', + ) if not header: LOG.error('Filename was expected but was not provided in response') sys.exit(1) - output_path = os.path.join(tempfile.mkdtemp(prefix='git-pw'), - header.group(1)) + if output: + output_path = None + if output.fileno() != pty.STDOUT_FILENO: + LOG.debug('Saving to %s', output.name) + output_path = output.name - with open(output_path, 'wb') as output_file: - LOG.debug('Saving to %s', output_path) # we use iter_content because patches can be binary for block in rsp.iter_content(1024): - output_file.write(block) + output.write(block) + else: + output_path = os.path.join( + tempfile.mkdtemp(prefix='git-pw'), header.group(1), + ) + with open(output_path, 'wb') as output_file: + LOG.debug('Saving to %s', output_path) + # we use iter_content because patches can be binary + for block in rsp.iter_content(1024): + output_file.write(block) return output_path @@ -233,7 +283,7 @@ params = params or [] params.append(('project', _get_project())) - return get(url, params).json() + return _get(url, params).json() def detail(resource_type, resource_id, params=None): @@ -253,11 +303,49 @@ # NOTE(stephenfin): All resources must have a trailing '/' url = '/'.join([_get_server(), resource_type, str(resource_id), '']) - return get(url, params, stream=False).json() + return _get(url, params, stream=False).json() + + +def create(resource_type, data): + # type: (str, dict) -> dict + """Create a new API resource. + + POST /{resource}/ + + Arguments: + resource_type: The resource endpoint name. + params: Fields to update. + + Returns: + A dictionary representing the detailed view of a given resource. + """ + # NOTE(stephenfin): All resources must have a trailing '/' + url = '/'.join([_get_server(), resource_type, '']) + + return _post(url, data).json() + + +def delete(resource_type, resource_id): + # type: (str, Union[str, int]) -> None + """Delete a specific API resource. + + DELETE /{resource}/{resourceID}/ + + Arguments: + resource_type: The resource endpoint name. + resource_id: The ID for the specific resource. + + Returns: + A dictionary representing the detailed view of a given resource. + """ + # NOTE(stephenfin): All resources must have a trailing '/' + url = '/'.join([_get_server(), resource_type, str(resource_id), '']) + + _delete(url) def update(resource_type, resource_id, data): - # type: (str, int, dict) -> dict + # type: (str, Union[int, str], dict) -> dict """Update a specific API resource. PATCH /{resource}/{resourceID}/ @@ -273,7 +361,24 @@ # NOTE(stephenfin): All resources must have a trailing '/' url = '/'.join([_get_server(), resource_type, str(resource_id), '']) - return patch(url, data).json() + return _patch(url, data).json() + + +def validate_minimum_version(min_version, msg): + # type: (Tuple[int, int], str) -> Callable[[Any], Any] + + def inner(f): + @click.pass_context + def new_func(ctx, *args, **kwargs): + if version() < min_version: + LOG.error(msg) + sys.exit(1) + + return ctx.invoke(f, *args, **kwargs) + + return update_wrapper(new_func, f) + + return inner def validate_multiple_filter_support(f): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/git_pw/bundle.py new/git-pw-1.9.0/git_pw/bundle.py --- old/git-pw-1.8.1/git_pw/bundle.py 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/git_pw/bundle.py 2020-04-18 01:09:43.000000000 +0200 @@ -3,7 +3,6 @@ """ import logging -import pty import sys import click @@ -72,31 +71,13 @@ path = None bundle = _get_bundle(bundle_id) - if output: - content = api.get(bundle['mbox']).content - - output.write(content) - - if output.fileno() != pty.STDOUT_FILENO: - path = output.name - else: - path = api.download(bundle['mbox']) + path = api.download(bundle['mbox'], output=output) if path: LOG.info('Downloaded bundle to %s', path) [email protected](name='show') [email protected]_options [email protected]('bundle_id') -def show_cmd(fmt, bundle_id): - """Show information about bundle. - - Retrieve Patchwork metadata for a bundle. - """ - LOG.debug('Showing bundle: id=%s', bundle_id) - - bundle = _get_bundle(bundle_id) +def _show_bundle(bundle, fmt): def _format_patch(patch): return '%-4d %s' % (patch.get('id'), patch.get('name')) @@ -117,6 +98,21 @@ utils.echo(output, ['Property', 'Value'], fmt=fmt) [email protected](name='show') [email protected]_options [email protected]('bundle_id') +def show_cmd(fmt, bundle_id): + """Show information about bundle. + + Retrieve Patchwork metadata for a bundle. + """ + LOG.debug('Showing bundle: id=%s', bundle_id) + + bundle = _get_bundle(bundle_id) + + _show_bundle(bundle, fmt) + + @click.command(name='list') @click.option('--owner', metavar='OWNER', multiple=True, help='Show only bundles with these owners. Should be an email, ' @@ -171,3 +167,153 @@ output[-1].append(item[idx]) utils.echo_via_pager(output, headers, fmt=fmt) + + [email protected](name='create') [email protected]('--public/--private', default=False, + help='Allow other users to view this bundle. If private, only ' + 'you will be able to see this bundle.') [email protected]('name') [email protected]('patch_ids', type=click.INT, nargs=-1, required=True) [email protected]_minimum_version( + (1, 2), 'Creating bundles is only supported from API version 1.2', +) [email protected]_options +def create_cmd(name, patch_ids, public, fmt): + """Create a bundle. + + Create a bundle with the given NAME and patches from PATCH_ID. + + Requires API version 1.2 or greater. + """ + LOG.debug('Create bundle: name=%s, patches=%s, public=%s', + name, patch_ids, public) + + data = [ + ('name', name), + ('patches', patch_ids), + ('public', public), + ] + + bundle = api.create('bundles', data) + + _show_bundle(bundle, fmt) + + [email protected](name='update') [email protected]('--name') [email protected]('--patch', 'patch_ids', type=click.INT, multiple=True, + help='Add the specified patch(es) to the bundle.') [email protected]('--public/--private', default=None, + help='Allow other users to view this bundle. If private, only ' + 'you will be able to see this bundle.') [email protected]('bundle_id') [email protected]_minimum_version( + (1, 2), 'Updating bundles is only supported from API version 1.2', +) [email protected]_options +def update_cmd(bundle_id, name, patch_ids, public, fmt): + """Update a bundle. + + Update bundle BUNDLE_ID. If PATCH_IDs are specified, this will overwrite + all patches in the bundle. Use 'bundle add' and 'bundle remove' to add or + remove patches. + + Requires API version 1.2 or greater. + """ + LOG.debug( + 'Updating bundle: id=%s, name=%s, patches=%s, public=%s', + bundle_id, name, patch_ids, public, + ) + + data = [] + + for key, value in [('name', name), ('public', public)]: + if value is None: + continue + + data.append((key, value)) + + if patch_ids: # special case patches to ignore the empty set + data.append(('patches', patch_ids)) + + bundle = api.update('bundles', bundle_id, data) + + _show_bundle(bundle, fmt) + + [email protected](name='delete') [email protected]('bundle_id') [email protected]_minimum_version( + (1, 2), 'Deleting bundles is only supported from API version 1.2', +) [email protected]_options +def delete_cmd(bundle_id, fmt): + """Delete a bundle. + + Delete bundle BUNDLE_ID. + + Requires API version 1.2 or greater. + """ + LOG.debug('Delete bundle: id=%s', bundle_id) + + api.delete('bundles', bundle_id) + + [email protected](name='add') [email protected]('bundle_id') [email protected]('patch_ids', type=click.INT, nargs=-1, required=True) [email protected]_minimum_version( + (1, 2), 'Modifying bundles is only supported from API version 1.2', +) [email protected]_options +def add_cmd(bundle_id, patch_ids, fmt): + """Add one or more patches to a bundle. + + Append the provided PATCH_IDS to bundle BUNDLE_ID. + + Requires API version 1.2 or greater. + """ + LOG.debug('Add to bundle: id=%s, patches=%s', bundle_id, patch_ids) + + bundle = _get_bundle(bundle_id) + + data = [ + ('patches', patch_ids + tuple([p['id'] for p in bundle['patches']])), + ] + + bundle = api.update('bundles', bundle_id, data) + + _show_bundle(bundle, fmt) + + [email protected](name='remove') [email protected]('bundle_id') [email protected]('patch_ids', type=click.INT, nargs=-1, required=True) [email protected]_minimum_version( + (1, 2), 'Modifying bundles is only supported from API version 1.2', +) [email protected]_options +def remove_cmd(bundle_id, patch_ids, fmt): + """Remove one or more patches from a bundle. + + Remove the provided PATCH_IDS to bundle BUNDLE_ID. + + Requires API version 1.2 or greater. + """ + LOG.debug('Remove from bundle: id=%s, patches=%s', bundle_id, patch_ids) + + bundle = _get_bundle(bundle_id) + + patches = [p['id'] for p in bundle['patches'] if p['id'] not in patch_ids] + if not patches: + LOG.error( + 'Bundles cannot be empty. Consider deleting the bundle instead' + ) + sys.exit(1) + + data = [('patches', tuple(patches))] + + bundle = api.update('bundles', bundle_id, data) + + _show_bundle(bundle, fmt) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/git_pw/patch.py new/git-pw-1.9.0/git_pw/patch.py --- old/git-pw-1.8.1/git_pw/patch.py 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/git_pw/patch.py 2020-04-18 01:09:43.000000000 +0200 @@ -75,24 +75,20 @@ path = None patch = api.detail('patches', patch_id) - if output: - if fmt == 'diff': - content = patch['diff'] + if fmt == 'diff': + if output: + output.write(patch['diff']) + if output.fileno() != pty.STDOUT_FILENO: + path = output.name else: - content = api.get(patch['mbox']).content - - output.write(content) - - if output.fileno() != pty.STDOUT_FILENO: - path = output.name - else: - if fmt == 'diff': # TODO(stephenfin): We discard the 'diff' field so we can get the # filename and save to the correct file. We should expose this # information via the API - path = api.download(patch['mbox'].replace('mbox', 'raw')) - else: - path = api.download(patch['mbox']) + path = api.download( + patch['mbox'].replace('mbox', 'raw'), output=output, + ) + else: + path = api.download(patch['mbox'], output=output) if path: LOG.info('Downloaded patch to %s', path) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/git_pw/series.py new/git-pw-1.9.0/git_pw/series.py --- old/git-pw-1.8.1/git_pw/series.py 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/git_pw/series.py 2020-04-18 01:09:43.000000000 +0200 @@ -3,7 +3,6 @@ """ import logging -import pty import arrow import click @@ -51,15 +50,7 @@ path = None series = api.detail('series', series_id) - if output: - content = api.get(series['mbox']).content - - output.write(content) - - if output.fileno() != pty.STDOUT_FILENO: - path = output.name - else: - path = api.download(series['mbox']) + path = api.download(series['mbox'], output=output) if path: LOG.info('Downloaded series to %s', path) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/git_pw/shell.py new/git-pw-1.9.0/git_pw/shell.py --- old/git-pw-1.8.1/git_pw/shell.py 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/git_pw/shell.py 2020-04-18 01:09:43.000000000 +0200 @@ -123,3 +123,8 @@ bundle.add_command(bundle_cmds.show_cmd) bundle.add_command(bundle_cmds.download_cmd) bundle.add_command(bundle_cmds.list_cmd) +bundle.add_command(bundle_cmds.create_cmd) +bundle.add_command(bundle_cmds.update_cmd) +bundle.add_command(bundle_cmds.delete_cmd) +bundle.add_command(bundle_cmds.add_cmd) +bundle.add_command(bundle_cmds.remove_cmd) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/git_pw.egg-info/PKG-INFO new/git-pw-1.9.0/git_pw.egg-info/PKG-INFO --- old/git-pw-1.8.1/git_pw.egg-info/PKG-INFO 2020-03-31 18:06:45.000000000 +0200 +++ new/git-pw-1.9.0/git_pw.egg-info/PKG-INFO 2020-04-18 01:10:02.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.2 Name: git-pw -Version: 1.8.1 +Version: 1.9.0 Summary: Git-Patchwork integration tool Home-page: https://github.com/getpatchwork/git-pw Author: Stephen Finucane diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/git_pw.egg-info/SOURCES.txt new/git-pw-1.9.0/git_pw.egg-info/SOURCES.txt --- old/git-pw-1.8.1/git_pw.egg-info/SOURCES.txt 2020-03-31 18:06:45.000000000 +0200 +++ new/git-pw-1.9.0/git_pw.egg-info/SOURCES.txt 2020-04-18 01:10:02.000000000 +0200 @@ -33,10 +33,15 @@ git_pw.egg-info/pbr.json git_pw.egg-info/requires.txt git_pw.egg-info/top_level.txt +man/git-pw-bundle-add.1 man/git-pw-bundle-apply.1 +man/git-pw-bundle-create.1 +man/git-pw-bundle-delete.1 man/git-pw-bundle-download.1 man/git-pw-bundle-list.1 +man/git-pw-bundle-remove.1 man/git-pw-bundle-show.1 +man/git-pw-bundle-update.1 man/git-pw-bundle.1 man/git-pw-patch-apply.1 man/git-pw-patch-download.1 @@ -51,6 +56,7 @@ man/git-pw-series.1 man/git-pw.1 releasenotes/notes/api-v1-1-5c804713ef435739.yaml +releasenotes/notes/bundle-crud-47aadae6eb7a20ad.yaml releasenotes/notes/drop-pypy-support-f670deb05ef527fe.yaml releasenotes/notes/drop-python34-support-5e01360fff605972.yaml releasenotes/notes/enforce-filtering-by-project-59ed29c4b7edc0a5.yaml @@ -68,6 +74,7 @@ releasenotes/notes/issue-49-865c4f1657b97fce.yaml releasenotes/notes/passthrough-git-am-arguments-23cd0b292304d648.yaml releasenotes/notes/patch-states-b88240569f8474f1.yaml +releasenotes/notes/python-2-deprecation-c87e311384eab29b.yaml releasenotes/notes/random-fixes-3da473a63c253f2d.yaml releasenotes/notes/remove-python-3-2-3-3-support-8987031bed2c0333.yaml releasenotes/notes/require-server-version-93ac0818c293b85e.yaml diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/git_pw.egg-info/pbr.json new/git-pw-1.9.0/git_pw.egg-info/pbr.json --- old/git-pw-1.8.1/git_pw.egg-info/pbr.json 2020-03-31 18:06:45.000000000 +0200 +++ new/git-pw-1.9.0/git_pw.egg-info/pbr.json 2020-04-18 01:10:02.000000000 +0200 @@ -1 +1 @@ -{"git_version": "786c0f0", "is_release": true} \ No newline at end of file +{"git_version": "f1f4178", "is_release": true} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/man/git-pw-bundle-add.1 new/git-pw-1.9.0/man/git-pw-bundle-add.1 --- old/git-pw-1.8.1/man/git-pw-bundle-add.1 1970-01-01 01:00:00.000000000 +0100 +++ new/git-pw-1.9.0/man/git-pw-bundle-add.1 2020-04-18 01:09:43.000000000 +0200 @@ -0,0 +1,16 @@ +.TH "GIT-PW BUNDLE ADD" "1" "2020-04-17" "1.9.0" "git-pw bundle add Manual" +.SH NAME +git-pw\-bundle\-add \- Add one or more patches to a bundle. +.SH SYNOPSIS +.B git-pw bundle add +[OPTIONS] BUNDLE_ID PATCH_IDS... +.SH DESCRIPTION +Add one or more patches to a bundle. +.PP +Append the provided PATCH_IDS to bundle BUNDLE_ID. +.PP +Requires API version 1.2 or greater. +.SH OPTIONS +.TP +\fB\-f,\fP \-\-format [simple|table|csv] +Output format. Defaults to the value of 'git config pw.format' else 'table'. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/man/git-pw-bundle-apply.1 new/git-pw-1.9.0/man/git-pw-bundle-apply.1 --- old/git-pw-1.8.1/man/git-pw-bundle-apply.1 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/man/git-pw-bundle-apply.1 2020-04-18 01:09:43.000000000 +0200 @@ -1,4 +1,4 @@ -.TH "GIT-PW BUNDLE APPLY" "1" "08-Dec-2019" "1.8.0" "git-pw bundle apply Manual" +.TH "GIT-PW BUNDLE APPLY" "1" "2020-04-17" "1.9.0" "git-pw bundle apply Manual" .SH NAME git-pw\-bundle\-apply \- Apply bundle. .SH SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/man/git-pw-bundle-create.1 new/git-pw-1.9.0/man/git-pw-bundle-create.1 --- old/git-pw-1.8.1/man/git-pw-bundle-create.1 1970-01-01 01:00:00.000000000 +0100 +++ new/git-pw-1.9.0/man/git-pw-bundle-create.1 2020-04-18 01:09:43.000000000 +0200 @@ -0,0 +1,19 @@ +.TH "GIT-PW BUNDLE CREATE" "1" "2020-04-17" "1.9.0" "git-pw bundle create Manual" +.SH NAME +git-pw\-bundle\-create \- Create a bundle. +.SH SYNOPSIS +.B git-pw bundle create +[OPTIONS] NAME PATCH_IDS... +.SH DESCRIPTION +Create a bundle. +.PP +Create a bundle with the given NAME and patches from PATCH_ID. +.PP +Requires API version 1.2 or greater. +.SH OPTIONS +.TP +\fB\-\-public\fP / \-\-private +Allow other users to view this bundle. If private, only you will be able to see this bundle. +.TP +\fB\-f,\fP \-\-format [simple|table|csv] +Output format. Defaults to the value of 'git config pw.format' else 'table'. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/man/git-pw-bundle-delete.1 new/git-pw-1.9.0/man/git-pw-bundle-delete.1 --- old/git-pw-1.8.1/man/git-pw-bundle-delete.1 1970-01-01 01:00:00.000000000 +0100 +++ new/git-pw-1.9.0/man/git-pw-bundle-delete.1 2020-04-18 01:09:43.000000000 +0200 @@ -0,0 +1,16 @@ +.TH "GIT-PW BUNDLE DELETE" "1" "2020-04-17" "1.9.0" "git-pw bundle delete Manual" +.SH NAME +git-pw\-bundle\-delete \- Delete a bundle. +.SH SYNOPSIS +.B git-pw bundle delete +[OPTIONS] BUNDLE_ID +.SH DESCRIPTION +Delete a bundle. +.PP +Delete bundle BUNDLE_ID. +.PP +Requires API version 1.2 or greater. +.SH OPTIONS +.TP +\fB\-f,\fP \-\-format [simple|table|csv] +Output format. Defaults to the value of 'git config pw.format' else 'table'. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/man/git-pw-bundle-download.1 new/git-pw-1.9.0/man/git-pw-bundle-download.1 --- old/git-pw-1.8.1/man/git-pw-bundle-download.1 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/man/git-pw-bundle-download.1 2020-04-18 01:09:43.000000000 +0200 @@ -1,4 +1,4 @@ -.TH "GIT-PW BUNDLE DOWNLOAD" "1" "08-Dec-2019" "1.8.0" "git-pw bundle download Manual" +.TH "GIT-PW BUNDLE DOWNLOAD" "1" "2020-04-17" "1.9.0" "git-pw bundle download Manual" .SH NAME git-pw\-bundle\-download \- Download bundle in mbox format. .SH SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/man/git-pw-bundle-list.1 new/git-pw-1.9.0/man/git-pw-bundle-list.1 --- old/git-pw-1.8.1/man/git-pw-bundle-list.1 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/man/git-pw-bundle-list.1 2020-04-18 01:09:43.000000000 +0200 @@ -1,4 +1,4 @@ -.TH "GIT-PW BUNDLE LIST" "1" "08-Dec-2019" "1.8.0" "git-pw bundle list Manual" +.TH "GIT-PW BUNDLE LIST" "1" "2020-04-17" "1.9.0" "git-pw bundle list Manual" .SH NAME git-pw\-bundle\-list \- List bundles. .SH SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/man/git-pw-bundle-remove.1 new/git-pw-1.9.0/man/git-pw-bundle-remove.1 --- old/git-pw-1.8.1/man/git-pw-bundle-remove.1 1970-01-01 01:00:00.000000000 +0100 +++ new/git-pw-1.9.0/man/git-pw-bundle-remove.1 2020-04-18 01:09:43.000000000 +0200 @@ -0,0 +1,16 @@ +.TH "GIT-PW BUNDLE REMOVE" "1" "2020-04-17" "1.9.0" "git-pw bundle remove Manual" +.SH NAME +git-pw\-bundle\-remove \- Remove one or more patches from a bundle. +.SH SYNOPSIS +.B git-pw bundle remove +[OPTIONS] BUNDLE_ID PATCH_IDS... +.SH DESCRIPTION +Remove one or more patches from a bundle. +.PP +Remove the provided PATCH_IDS to bundle BUNDLE_ID. +.PP +Requires API version 1.2 or greater. +.SH OPTIONS +.TP +\fB\-f,\fP \-\-format [simple|table|csv] +Output format. Defaults to the value of 'git config pw.format' else 'table'. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/man/git-pw-bundle-show.1 new/git-pw-1.9.0/man/git-pw-bundle-show.1 --- old/git-pw-1.8.1/man/git-pw-bundle-show.1 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/man/git-pw-bundle-show.1 2020-04-18 01:09:43.000000000 +0200 @@ -1,4 +1,4 @@ -.TH "GIT-PW BUNDLE SHOW" "1" "08-Dec-2019" "1.8.0" "git-pw bundle show Manual" +.TH "GIT-PW BUNDLE SHOW" "1" "2020-04-17" "1.9.0" "git-pw bundle show Manual" .SH NAME git-pw\-bundle\-show \- Show information about bundle. .SH SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/man/git-pw-bundle-update.1 new/git-pw-1.9.0/man/git-pw-bundle-update.1 --- old/git-pw-1.8.1/man/git-pw-bundle-update.1 1970-01-01 01:00:00.000000000 +0100 +++ new/git-pw-1.9.0/man/git-pw-bundle-update.1 2020-04-18 01:09:43.000000000 +0200 @@ -0,0 +1,27 @@ +.TH "GIT-PW BUNDLE UPDATE" "1" "2020-04-17" "1.9.0" "git-pw bundle update Manual" +.SH NAME +git-pw\-bundle\-update \- Update a bundle. +.SH SYNOPSIS +.B git-pw bundle update +[OPTIONS] BUNDLE_ID +.SH DESCRIPTION +Update a bundle. +.PP +Update bundle BUNDLE_ID. If PATCH_IDs are specified, this will overwrite +all patches in the bundle. Use 'bundle add' and 'bundle remove' to add or +remove patches. +.PP +Requires API version 1.2 or greater. +.SH OPTIONS +.TP +\fB\-\-name\fP TEXT +.PP +.TP +\fB\-\-patch\fP INTEGER +Add the specified patch(es) to the bundle. +.TP +\fB\-\-public\fP / \-\-private +Allow other users to view this bundle. If private, only you will be able to see this bundle. +.TP +\fB\-f,\fP \-\-format [simple|table|csv] +Output format. Defaults to the value of 'git config pw.format' else 'table'. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/man/git-pw-bundle.1 new/git-pw-1.9.0/man/git-pw-bundle.1 --- old/git-pw-1.8.1/man/git-pw-bundle.1 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/man/git-pw-bundle.1 2020-04-18 01:09:43.000000000 +0200 @@ -1,4 +1,4 @@ -.TH "GIT-PW BUNDLE" "1" "08-Dec-2019" "1.8.0" "git-pw bundle Manual" +.TH "GIT-PW BUNDLE" "1" "2020-04-17" "1.9.0" "git-pw bundle Manual" .SH NAME git-pw\-bundle \- Interact with bundles. .SH SYNOPSIS @@ -31,3 +31,23 @@ \fBlist\fP List bundles. See \fBgit-pw bundle-list(1)\fP for full documentation on the \fBlist\fP command. +.PP +\fBcreate\fP + Create a bundle. + See \fBgit-pw bundle-create(1)\fP for full documentation on the \fBcreate\fP command. +.PP +\fBupdate\fP + Update a bundle. + See \fBgit-pw bundle-update(1)\fP for full documentation on the \fBupdate\fP command. +.PP +\fBdelete\fP + Delete a bundle. + See \fBgit-pw bundle-delete(1)\fP for full documentation on the \fBdelete\fP command. +.PP +\fBadd\fP + Add one or more patches to a bundle. + See \fBgit-pw bundle-add(1)\fP for full documentation on the \fBadd\fP command. +.PP +\fBremove\fP + Remove one or more patches from a bundle. + See \fBgit-pw bundle-remove(1)\fP for full documentation on the \fBremove\fP command. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/man/git-pw-patch-apply.1 new/git-pw-1.9.0/man/git-pw-patch-apply.1 --- old/git-pw-1.8.1/man/git-pw-patch-apply.1 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/man/git-pw-patch-apply.1 2020-04-18 01:09:43.000000000 +0200 @@ -1,4 +1,4 @@ -.TH "GIT-PW PATCH APPLY" "1" "08-Dec-2019" "1.8.0" "git-pw patch apply Manual" +.TH "GIT-PW PATCH APPLY" "1" "2020-04-17" "1.9.0" "git-pw patch apply Manual" .SH NAME git-pw\-patch\-apply \- Apply patch. .SH SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/man/git-pw-patch-download.1 new/git-pw-1.9.0/man/git-pw-patch-download.1 --- old/git-pw-1.8.1/man/git-pw-patch-download.1 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/man/git-pw-patch-download.1 2020-04-18 01:09:43.000000000 +0200 @@ -1,4 +1,4 @@ -.TH "GIT-PW PATCH DOWNLOAD" "1" "08-Dec-2019" "1.8.0" "git-pw patch download Manual" +.TH "GIT-PW PATCH DOWNLOAD" "1" "2020-04-17" "1.9.0" "git-pw patch download Manual" .SH NAME git-pw\-patch\-download \- Download patch in diff or mbox format. .SH SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/man/git-pw-patch-list.1 new/git-pw-1.9.0/man/git-pw-patch-list.1 --- old/git-pw-1.8.1/man/git-pw-patch-list.1 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/man/git-pw-patch-list.1 2020-04-18 01:09:43.000000000 +0200 @@ -1,4 +1,4 @@ -.TH "GIT-PW PATCH LIST" "1" "08-Dec-2019" "1.8.0" "git-pw patch list Manual" +.TH "GIT-PW PATCH LIST" "1" "2020-04-17" "1.9.0" "git-pw patch list Manual" .SH NAME git-pw\-patch\-list \- List patches. .SH SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/man/git-pw-patch-show.1 new/git-pw-1.9.0/man/git-pw-patch-show.1 --- old/git-pw-1.8.1/man/git-pw-patch-show.1 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/man/git-pw-patch-show.1 2020-04-18 01:09:43.000000000 +0200 @@ -1,4 +1,4 @@ -.TH "GIT-PW PATCH SHOW" "1" "08-Dec-2019" "1.8.0" "git-pw patch show Manual" +.TH "GIT-PW PATCH SHOW" "1" "2020-04-17" "1.9.0" "git-pw patch show Manual" .SH NAME git-pw\-patch\-show \- Show information about patch. .SH SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/man/git-pw-patch-update.1 new/git-pw-1.9.0/man/git-pw-patch-update.1 --- old/git-pw-1.8.1/man/git-pw-patch-update.1 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/man/git-pw-patch-update.1 2020-04-18 01:09:43.000000000 +0200 @@ -1,4 +1,4 @@ -.TH "GIT-PW PATCH UPDATE" "1" "08-Dec-2019" "1.8.0" "git-pw patch update Manual" +.TH "GIT-PW PATCH UPDATE" "1" "2020-04-17" "1.9.0" "git-pw patch update Manual" .SH NAME git-pw\-patch\-update \- Update one or more patches. .SH SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/man/git-pw-patch.1 new/git-pw-1.9.0/man/git-pw-patch.1 --- old/git-pw-1.8.1/man/git-pw-patch.1 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/man/git-pw-patch.1 2020-04-18 01:09:43.000000000 +0200 @@ -1,4 +1,4 @@ -.TH "GIT-PW PATCH" "1" "08-Dec-2019" "1.8.0" "git-pw patch Manual" +.TH "GIT-PW PATCH" "1" "2020-04-17" "1.9.0" "git-pw patch Manual" .SH NAME git-pw\-patch \- Interact with patches. .SH SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/man/git-pw-series-apply.1 new/git-pw-1.9.0/man/git-pw-series-apply.1 --- old/git-pw-1.8.1/man/git-pw-series-apply.1 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/man/git-pw-series-apply.1 2020-04-18 01:09:43.000000000 +0200 @@ -1,4 +1,4 @@ -.TH "GIT-PW SERIES APPLY" "1" "08-Dec-2019" "1.8.0" "git-pw series apply Manual" +.TH "GIT-PW SERIES APPLY" "1" "2020-04-17" "1.9.0" "git-pw series apply Manual" .SH NAME git-pw\-series\-apply \- Apply series. .SH SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/man/git-pw-series-download.1 new/git-pw-1.9.0/man/git-pw-series-download.1 --- old/git-pw-1.8.1/man/git-pw-series-download.1 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/man/git-pw-series-download.1 2020-04-18 01:09:43.000000000 +0200 @@ -1,4 +1,4 @@ -.TH "GIT-PW SERIES DOWNLOAD" "1" "08-Dec-2019" "1.8.0" "git-pw series download Manual" +.TH "GIT-PW SERIES DOWNLOAD" "1" "2020-04-17" "1.9.0" "git-pw series download Manual" .SH NAME git-pw\-series\-download \- Download series in mbox format. .SH SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/man/git-pw-series-list.1 new/git-pw-1.9.0/man/git-pw-series-list.1 --- old/git-pw-1.8.1/man/git-pw-series-list.1 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/man/git-pw-series-list.1 2020-04-18 01:09:43.000000000 +0200 @@ -1,4 +1,4 @@ -.TH "GIT-PW SERIES LIST" "1" "08-Dec-2019" "1.8.0" "git-pw series list Manual" +.TH "GIT-PW SERIES LIST" "1" "2020-04-17" "1.9.0" "git-pw series list Manual" .SH NAME git-pw\-series\-list \- List series. .SH SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/man/git-pw-series-show.1 new/git-pw-1.9.0/man/git-pw-series-show.1 --- old/git-pw-1.8.1/man/git-pw-series-show.1 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/man/git-pw-series-show.1 2020-04-18 01:09:43.000000000 +0200 @@ -1,4 +1,4 @@ -.TH "GIT-PW SERIES SHOW" "1" "08-Dec-2019" "1.8.0" "git-pw series show Manual" +.TH "GIT-PW SERIES SHOW" "1" "2020-04-17" "1.9.0" "git-pw series show Manual" .SH NAME git-pw\-series\-show \- Show information about series. .SH SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/man/git-pw-series.1 new/git-pw-1.9.0/man/git-pw-series.1 --- old/git-pw-1.8.1/man/git-pw-series.1 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/man/git-pw-series.1 2020-04-18 01:09:43.000000000 +0200 @@ -1,4 +1,4 @@ -.TH "GIT-PW SERIES" "1" "08-Dec-2019" "1.8.0" "git-pw series Manual" +.TH "GIT-PW SERIES" "1" "2020-04-17" "1.9.0" "git-pw series Manual" .SH NAME git-pw\-series \- Interact with series. .SH SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/man/git-pw.1 new/git-pw-1.9.0/man/git-pw.1 --- old/git-pw-1.8.1/man/git-pw.1 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/man/git-pw.1 2020-04-18 01:09:43.000000000 +0200 @@ -1,4 +1,4 @@ -.TH "GIT-PW" "1" "08-Dec-2019" "1.8.0" "git-pw Manual" +.TH "GIT-PW" "1" "2020-04-17" "1.9.0" "git-pw Manual" .SH NAME git-pw \- git-pw is a tool for integrating Git with... .SH SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/releasenotes/notes/bundle-crud-47aadae6eb7a20ad.yaml new/git-pw-1.9.0/releasenotes/notes/bundle-crud-47aadae6eb7a20ad.yaml --- old/git-pw-1.8.1/releasenotes/notes/bundle-crud-47aadae6eb7a20ad.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/git-pw-1.9.0/releasenotes/notes/bundle-crud-47aadae6eb7a20ad.yaml 2020-04-18 01:09:43.000000000 +0200 @@ -0,0 +1,16 @@ +--- +features: + - | + The following ``bundle`` commands have been added: + + - ``bundle create`` + - ``bundle update`` + - ``bundle delete`` + - ``bundle add`` + - ``bundle remove`` + + Together, these allow for creation, modification and deletion of bundles. + Bundles are custom, user-defined groups of patches that can be used to keep + patch lists, preserving order, for future inclusion in a tree. + + These commands require API v1.2. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/releasenotes/notes/python-2-deprecation-c87e311384eab29b.yaml new/git-pw-1.9.0/releasenotes/notes/python-2-deprecation-c87e311384eab29b.yaml --- old/git-pw-1.8.1/releasenotes/notes/python-2-deprecation-c87e311384eab29b.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/git-pw-1.9.0/releasenotes/notes/python-2-deprecation-c87e311384eab29b.yaml 2020-04-18 01:09:43.000000000 +0200 @@ -0,0 +1,5 @@ +--- +other: + - | + *git-pw* 1.9.0 will be the last version to support Python 2.7. *git-pw* + 2.0.0 will require Python 3.5 or greater. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/tests/test_bundle.py new/git-pw-1.9.0/tests/test_bundle.py --- old/git-pw-1.8.1/tests/test_bundle.py 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/tests/test_bundle.py 2020-04-18 01:09:43.000000000 +0200 @@ -1,6 +1,7 @@ import unittest from click.testing import CliRunner as CLIRunner +from click import utils as click_utils import mock from git_pw import bundle @@ -94,10 +95,9 @@ @mock.patch('git_pw.bundle._get_bundle') @mock.patch('git_pw.api.download') [email protected]('git_pw.api.get') class DownloadTestCase(unittest.TestCase): - def test_download(self, mock_get, mock_download, mock_get_bundle): + def test_download(self, mock_download, mock_get_bundle): """Validate standard behavior.""" rsp = {'mbox': 'http://example.com/api/patches/123/mbox/'} @@ -109,33 +109,24 @@ assert result.exit_code == 0, result mock_get_bundle.assert_called_once_with('123') - mock_download.assert_called_once_with(rsp['mbox']) - mock_get.assert_not_called() + mock_download.assert_called_once_with(rsp['mbox'], output=None) - def test_download_to_file(self, mock_get, mock_download, mock_get_bundle): + def test_download_to_file(self, mock_download, mock_get_bundle): """Validate downloading to a file.""" - class MockResponse(object): - @property - def content(self): - return b'alpha-beta' - rsp = {'mbox': 'http://example.com/api/patches/123/mbox/'} mock_get_bundle.return_value = rsp - mock_get.return_value = MockResponse() runner = CLIRunner() - with runner.isolated_filesystem(): - result = runner.invoke(bundle.download_cmd, ['123', 'test.patch']) + result = runner.invoke(bundle.download_cmd, ['123', 'test.patch']) - assert result.exit_code == 0, result - - with open('test.patch') as output: - assert ['alpha-beta'] == output.readlines() + assert result.exit_code == 0, result mock_get_bundle.assert_called_once_with('123') - mock_get.assert_called_once_with(rsp['mbox']) - mock_download.assert_not_called() + mock_download.assert_called_once_with(rsp['mbox'], output=mock.ANY) + assert isinstance( + mock_download.call_args[1]['output'], click_utils.LazyFile, + ) class ShowTestCase(unittest.TestCase): @@ -154,7 +145,17 @@ 'project': { 'name': 'bar', }, - 'patches': [], + 'patches': [ + { + 'id': 42, + 'date': '2017-01-01 00:00:00', + 'web_url': 'https://example.com/project/foo/patch/123/', + 'msgid': '<[email protected]>', + 'list_archive_url': None, + 'name': 'Test', + 'mbox': 'https://example.com/project/foo/patch/123/mbox/', + }, + ], 'public': True, } @@ -317,3 +318,246 @@ # We shouldn't see a warning about multiple versions either assert not mock_log.warning.called + + [email protected]('git_pw.api.version', return_value=(1, 2)) [email protected]('git_pw.api.create') [email protected]('git_pw.utils.echo_via_pager') +class CreateTestCase(unittest.TestCase): + + @staticmethod + def _get_bundle(**kwargs): + return ShowTestCase._get_bundle(**kwargs) + + def test_create(self, mock_echo, mock_create, mock_version): + """Validate standard behavior.""" + + mock_create.return_value = self._get_bundle() + + runner = CLIRunner() + result = runner.invoke(bundle.create_cmd, ['hello', '1', '2']) + + assert result.exit_code == 0, result + mock_create.assert_called_once_with( + 'bundles', + [('name', 'hello'), ('patches', (1, 2)), ('public', False)] + ) + + def test_create_with_public(self, mock_echo, mock_create, mock_version): + """Validate behavior with --public option.""" + + mock_create.return_value = self._get_bundle() + + runner = CLIRunner() + result = runner.invoke(bundle.create_cmd, [ + 'hello', '1', '2', '--public']) + + assert result.exit_code == 0, result + mock_create.assert_called_once_with( + 'bundles', + [('name', 'hello'), ('patches', (1, 2)), ('public', True)] + ) + + @mock.patch('git_pw.api.LOG') + def test_create_api_v1_1( + self, mock_log, mock_echo, mock_create, mock_version + ): + + mock_version.return_value = (1, 1) + + runner = CLIRunner() + result = runner.invoke(bundle.create_cmd, ['hello', '1', '2']) + + assert result.exit_code == 1, result + assert mock_log.error.called + + [email protected]('git_pw.api.version', return_value=(1, 2)) [email protected]('git_pw.api.update') [email protected]('git_pw.api.detail') [email protected]('git_pw.utils.echo_via_pager') +class UpdateTestCase(unittest.TestCase): + + @staticmethod + def _get_bundle(**kwargs): + return ShowTestCase._get_bundle(**kwargs) + + def test_update(self, mock_echo, mock_detail, mock_update, mock_version): + """Validate standard behavior.""" + + mock_update.return_value = self._get_bundle() + + runner = CLIRunner() + result = runner.invoke( + bundle.update_cmd, + ['1', '--name', 'hello', '--patch', '1', '--patch', '2'], + ) + + assert result.exit_code == 0, result + mock_detail.assert_not_called() + mock_update.assert_called_once_with( + 'bundles', '1', [('name', 'hello'), ('patches', (1, 2))] + ) + + def test_update_with_public( + self, mock_echo, mock_detail, mock_update, mock_version, + ): + """Validate behavior with --public option.""" + + mock_update.return_value = self._get_bundle() + + runner = CLIRunner() + result = runner.invoke(bundle.update_cmd, ['1', '--public']) + + assert result.exit_code == 0, result + mock_detail.assert_not_called() + mock_update.assert_called_once_with('bundles', '1', [('public', True)]) + + @mock.patch('git_pw.api.LOG') + def test_update_api_v1_1( + self, mock_log, mock_echo, mock_detail, mock_update, mock_version, + ): + + mock_version.return_value = (1, 1) + + runner = CLIRunner() + result = runner.invoke(bundle.update_cmd, ['1', '--name', 'hello']) + + assert result.exit_code == 1, result + assert mock_log.error.called + + [email protected]('git_pw.api.version', return_value=(1, 2)) [email protected]('git_pw.api.delete') [email protected]('git_pw.utils.echo_via_pager') +class DeleteTestCase(unittest.TestCase): + + def test_delete(self, mock_echo, mock_delete, mock_version): + """Validate standard behavior.""" + + mock_delete.return_value = None + + runner = CLIRunner() + result = runner.invoke(bundle.delete_cmd, ['hello']) + + assert result.exit_code == 0, result + mock_delete.assert_called_once_with('bundles', 'hello') + + @mock.patch('git_pw.api.LOG') + def test_delete_api_v1_1( + self, mock_log, mock_echo, mock_delete, mock_version, + ): + """Validate standard behavior.""" + + mock_version.return_value = (1, 1) + + runner = CLIRunner() + result = runner.invoke(bundle.delete_cmd, ['hello']) + + assert result.exit_code == 1, result + assert mock_log.error.called + + [email protected]('git_pw.api.version', return_value=(1, 2)) [email protected]('git_pw.api.update') [email protected]('git_pw.api.detail') [email protected]('git_pw.utils.echo_via_pager') +class AddTestCase(unittest.TestCase): + + @staticmethod + def _get_bundle(**kwargs): + return ShowTestCase._get_bundle(**kwargs) + + def test_add( + self, mock_echo, mock_detail, mock_update, mock_version, + ): + """Validate standard behavior.""" + + mock_detail.return_value = self._get_bundle() + mock_update.return_value = self._get_bundle() + + runner = CLIRunner() + result = runner.invoke(bundle.add_cmd, ['1', '1', '2']) + + assert result.exit_code == 0, result + mock_detail.assert_called_once_with('bundles', '1') + mock_update.assert_called_once_with( + 'bundles', '1', [('patches', (1, 2, 42))], + ) + + @mock.patch('git_pw.api.LOG') + def test_add_api_v1_1( + self, mock_log, mock_echo, mock_detail, mock_update, mock_version, + ): + """Validate behavior with API v1.1.""" + + mock_version.return_value = (1, 1) + + runner = CLIRunner() + result = runner.invoke(bundle.add_cmd, ['1', '1', '2']) + + assert result.exit_code == 1, result + assert mock_log.error.called + + [email protected]('git_pw.api.version', return_value=(1, 2)) [email protected]('git_pw.api.update') [email protected]('git_pw.api.detail') [email protected]('git_pw.utils.echo_via_pager') +class RemoveTestCase(unittest.TestCase): + + @staticmethod + def _get_bundle(**kwargs): + return ShowTestCase._get_bundle(**kwargs) + + def test_remove( + self, mock_echo, mock_detail, mock_update, mock_version, + ): + """Validate standard behavior.""" + + mock_detail.return_value = self._get_bundle( + patches=[{'id': 1}, {'id': 2}, {'id': 3}], + ) + mock_update.return_value = self._get_bundle() + + runner = CLIRunner() + result = runner.invoke(bundle.remove_cmd, ['1', '1', '2']) + + assert result.exit_code == 0, result + mock_detail.assert_called_once_with('bundles', '1') + mock_update.assert_called_once_with( + 'bundles', '1', [('patches', (3,))], + ) + + @mock.patch('git_pw.bundle.LOG') + def test_remove_empty( + self, mock_log, mock_echo, mock_detail, mock_update, mock_version, + ): + """Validate behavior when deleting would remove all patches.""" + + mock_detail.return_value = self._get_bundle( + patches=[{'id': 1}, {'id': 2}, {'id': 3}], + ) + mock_update.return_value = self._get_bundle() + + runner = CLIRunner() + result = runner.invoke(bundle.remove_cmd, ['1', '1', '2', '3']) + + assert result.exit_code == 1, result.output + assert mock_log.error.called + mock_detail.assert_called_once_with('bundles', '1') + mock_update.assert_not_called() + + @mock.patch('git_pw.api.LOG') + def test_remove_api_v1_1( + self, mock_log, mock_echo, mock_detail, mock_update, mock_version, + ): + """Validate behavior with API v1.1.""" + + mock_version.return_value = (1, 1) + + runner = CLIRunner() + result = runner.invoke(bundle.remove_cmd, ['1', '1', '2']) + + assert result.exit_code == 1, result + assert mock_log.error.called diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/tests/test_patch.py new/git-pw-1.9.0/tests/test_patch.py --- old/git-pw-1.8.1/tests/test_patch.py 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/tests/test_patch.py 2020-04-18 01:09:43.000000000 +0200 @@ -2,6 +2,7 @@ import click from click.testing import CliRunner as CLIRunner +from click import utils as click_utils import mock from packaging import version @@ -92,7 +93,7 @@ assert result.exit_code == 0, result mock_detail.assert_called_once_with('patches', 123) - mock_download.assert_called_once_with(rsp['mbox']) + mock_download.assert_called_once_with(rsp['mbox'], output=None) assert mock_log.info.called def test_download_diff(self, mock_log, mock_download, mock_detail): @@ -106,42 +107,30 @@ assert result.exit_code == 0, result mock_detail.assert_called_once_with('patches', 123) - mock_download.assert_called_once_with(rsp['mbox'].replace( - 'mbox', 'raw')) + mock_download.assert_called_once_with( + rsp['mbox'].replace('mbox', 'raw'), output=None, + ) assert mock_log.info.called - @mock.patch('git_pw.api.get') - def test_download_to_file(self, mock_get, mock_log, mock_download, - mock_detail): + def test_download_to_file(self, mock_log, mock_download, mock_detail): """Validate behavior if downloading to a specific file.""" - class MockResponse(object): - @property - def content(self): - return b'alpha-beta' - rsp = {'mbox': 'hello, world', 'diff': 'test'} mock_detail.return_value = rsp - mock_get.return_value = MockResponse() runner = CLIRunner() - with runner.isolated_filesystem(): - result = runner.invoke(patch.download_cmd, - ['123', 'test.patch']) + result = runner.invoke(patch.download_cmd, ['123', 'test.patch']) - assert result.exit_code == 0, result - - with open('test.patch') as output: - assert ['alpha-beta'] == output.readlines() + assert result.exit_code == 0, result mock_detail.assert_called_once_with('patches', 123) - mock_download.assert_not_called() - mock_get.assert_called_once_with(rsp['mbox']) + mock_download.assert_called_once_with(rsp['mbox'], output=mock.ANY) + assert isinstance( + mock_download.call_args[1]['output'], click_utils.LazyFile, + ) assert mock_log.info.called - @mock.patch('git_pw.api.get') - def test_download_diff_to_file(self, mock_get, mock_log, mock_download, - mock_detail): + def test_download_diff_to_file(self, mock_log, mock_download, mock_detail): """Validate behavior if downloading a diff to a specific file.""" rsp = {'mbox': 'hello, world', 'diff': b'test'} @@ -159,7 +148,6 @@ mock_detail.assert_called_once_with('patches', 123) mock_download.assert_not_called() - mock_get.assert_not_called() assert mock_log.info.called diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/tests/test_series.py new/git-pw-1.9.0/tests/test_series.py --- old/git-pw-1.8.1/tests/test_series.py 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/tests/test_series.py 2020-04-18 01:09:43.000000000 +0200 @@ -1,6 +1,7 @@ import unittest from click.testing import CliRunner as CLIRunner +from click import utils as click_utils import mock from git_pw import series @@ -45,48 +46,36 @@ @mock.patch('git_pw.api.detail') @mock.patch('git_pw.api.download') [email protected]('git_pw.api.get') class DownloadTestCase(unittest.TestCase): - def test_download(self, mock_get, mock_download, mock_detail): + def test_download(self, mock_download, mock_detail): """Validate standard behavior.""" rsp = {'mbox': 'http://example.com/api/patches/123/mbox/'} mock_detail.return_value = rsp - mock_download.return_value = 'test.patch' runner = CLIRunner() result = runner.invoke(series.download_cmd, ['123']) assert result.exit_code == 0, result mock_detail.assert_called_once_with('series', 123) - mock_download.assert_called_once_with(rsp['mbox']) - mock_get.assert_not_called() + mock_download.assert_called_once_with(rsp['mbox'], output=None) - def test_download_to_file(self, mock_get, mock_download, mock_detail): + def test_download_to_file(self, mock_download, mock_detail): """Validate downloading to a file.""" - class MockResponse(object): - @property - def content(self): - return b'alpha-beta' - rsp = {'mbox': 'http://example.com/api/patches/123/mbox/'} mock_detail.return_value = rsp - mock_get.return_value = MockResponse() runner = CLIRunner() - with runner.isolated_filesystem(): - result = runner.invoke(series.download_cmd, ['123', 'test.patch']) - - assert result.exit_code == 0, result - - with open('test.patch') as output: - assert ['alpha-beta'] == output.readlines() + result = runner.invoke(series.download_cmd, ['123', 'test.patch']) + assert result.exit_code == 0, result mock_detail.assert_called_once_with('series', 123) - mock_get.assert_called_once_with(rsp['mbox']) - mock_download.assert_not_called() + mock_download.assert_called_once_with(rsp['mbox'], output=mock.ANY) + assert isinstance( + mock_download.call_args[1]['output'], click_utils.LazyFile, + ) class ShowTestCase(unittest.TestCase): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/git-pw-1.8.1/tox.ini new/git-pw-1.9.0/tox.ini --- old/git-pw-1.8.1/tox.ini 2020-03-31 18:06:27.000000000 +0200 +++ new/git-pw-1.9.0/tox.ini 2020-04-18 01:09:43.000000000 +0200 @@ -47,7 +47,7 @@ [testenv:man] deps = - click-man~=0.3.0 + click-man~=0.4.0 commands = click-man git-pw
