From 2af6f41b21205bdd192514a434fca2feba17725a Mon Sep 17 00:00:00 2001 From: Rolf Erik Lekang Date: Mon, 5 Aug 2019 08:40:26 +0200 Subject: [PATCH] feat: Add configuration to customize handling of dists Relates to #115 --- docs/configuration.rst | 7 +++++++ semantic_release/cli.py | 2 ++ semantic_release/defaults.cfg | 2 ++ semantic_release/pypi.py | 14 +++++++++----- tests/test_pypi.py | 21 +++++++++++++++++++++ 5 files changed, 41 insertions(+), 5 deletions(-) diff --git a/docs/configuration.rst b/docs/configuration.rst index fb64250ba..6d9288e5b 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -29,3 +29,10 @@ All configuration described here belongs in ``setup.cfg`` in a section: ``commit_message`` Long description to append to the version number. This can be useful to skip pipelines in your CI tool + +``dist_path`` + The relative path to the folder for dists configured for setuptools. This allows for + customized setuptools processes. Default dist. + +``remove_dist`` + Flag for whether the dist folder should be removed after a release. Default: true diff --git a/semantic_release/cli.py b/semantic_release/cli.py index 653509092..c13e409d8 100644 --- a/semantic_release/cli.py +++ b/semantic_release/cli.py @@ -164,6 +164,8 @@ def publish(**kwargs): password=os.environ.get('PYPI_PASSWORD'), # We are retrying, so we don't want errors for files that are already on PyPI. skip_existing=retry, + remove_dist=config.getboolean('semantic_release', 'remove_dist'), + path=config.get('semantic_release', 'dist_path'), ) if check_token(): diff --git a/semantic_release/defaults.cfg b/semantic_release/defaults.cfg index b2b142c2f..f0b520f82 100644 --- a/semantic_release/defaults.cfg +++ b/semantic_release/defaults.cfg @@ -8,3 +8,5 @@ commit_parser=semantic_release.history.angular_parser upload_to_pypi=true version_source=commit commit_message=Automatically generated by python-semantic-release +dist_path=dist +remove_dist=true diff --git a/semantic_release/pypi.py b/semantic_release/pypi.py index 28e89914d..03a694525 100644 --- a/semantic_release/pypi.py +++ b/semantic_release/pypi.py @@ -7,9 +7,11 @@ def upload_to_pypi( dists: str = 'sdist bdist_wheel', + path: str = 'dist', username: str = None, password: str = None, - skip_existing: bool = False + skip_existing: bool = False, + remove_dist: bool = True ): """Creates the wheel and uploads to pypi with twine. @@ -21,14 +23,16 @@ def upload_to_pypi( """ if username is None or password is None or username == "" or password == "": raise ImproperConfigurationError('Missing credentials for uploading') - run('rm -rf dist') + if remove_dist: + run(f'rm -rf {path}') run('python setup.py {}'.format(dists)) run( - 'twine upload -u {} -p {} {} {}'.format( + 'twine upload -u {} -p {} {} {}/*'.format( username, password, '--skip-existing' if skip_existing else '', - 'dist/*' + path ) ) - run('rm -rf dist') + if remove_dist: + run(f'rm -rf {path}') diff --git a/tests/test_pypi.py b/tests/test_pypi.py index c594d5fff..4613dcc5c 100644 --- a/tests/test_pypi.py +++ b/tests/test_pypi.py @@ -18,3 +18,24 @@ def test_upload_without_arguments(self, mock_run): mock.call('rm -rf dist') ] ) + + @mock.patch('semantic_release.pypi.run') + def test_upload_without_arguments(self, mock_run): + upload_to_pypi(username='username', password='password', remove_dist=False) + self.assertEqual( + mock_run.call_args_list, + [ + mock.call('python setup.py sdist bdist_wheel'), + mock.call('twine upload -u username -p password dist/*'), + ] + ) + + @mock.patch('semantic_release.pypi.run') + def test_upload_with_custom_path(self, mock_run): + upload_to_pypi(path='custom-dist', username='username', password='password') + args = mock_run.call_args_list + self.assertEqual(args[0], mock.call('rm -rf custom-dist'),) + self.assertEqual(args[1], mock.call('python setup.py sdist bdist_wheel'),) + self.assertEqual(args[2], mock.call( + 'twine upload -u username -p password custom-dist/*'),) + self.assertEqual(args[3], mock.call('rm -rf custom-dist'))