Skip to content

Commit

Permalink
Merge pull request #421 from zestsoftware/maurits-fix-reading-pypirc
Browse files Browse the repository at this point in the history
Fix reading pypirc
  • Loading branch information
reinout committed Jul 12, 2023
2 parents afd42a4 + 15c0445 commit fb76b21
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 34 deletions.
42 changes: 37 additions & 5 deletions zest/releaser/pypi.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,15 @@ def zest_releaser_config(self):

def _read_configfile(self):
"""Read the PyPI config file and store it (when valid)."""
if not os.path.exists(self.config_filename):
config_filename = self.config_filename
if not os.path.exists(config_filename) and not os.path.isabs(config_filename):
# When filename is .pypirc, we look in ~/.pypirc
config_filename = os.path.join(os.path.expanduser("~"), config_filename)
if not os.path.exists(config_filename):
self.config = None
return
self.config = ConfigParser(interpolation=None)
self.config.read(self.config_filename)
self.config.read(config_filename)

def twine_repository(self):
"""Gets the repository from Twine environment variables."""
Expand Down Expand Up @@ -274,12 +278,37 @@ class ZestReleaserConfig:
hooks_filename = None

def load_configs(self, pypirc_config_filename=DIST_CONFIG_FILE):
"""Load configs from several files.
The order is this:
- ~/.pypirc
- setup.cfg
- pyproject.toml
A later config file overwrites keys from an earlier config file.
I think this order makes the most sense.
Example: extra-message = [ci skip]
What I expect, is:
* Most packages won't have this setting.
* If you make releases for lots of packages, you probably set this in
your global ~/.pypirc.
* A few individual packages will explicitly set this.
They will expect this to have the effect that the extra message is
added to commits, regardless of who makes a release.
So this individual package setting should win.
* Finally, pyproject.toml is newer than setup.cfg, so it makes sense
that this file has the last say.
"""
setup_config = SetupConfig()
pypi_config = PypiConfig(config_filename=pypirc_config_filename)
pyproject_config = PyprojectTomlConfig()
combined_config = {}
# overwrite any duplicate keys in the following order:
for config in [setup_config, pypi_config, pyproject_config]:
config_files = [pypi_config]
if not self.omit_package_config_in_test:
config_files.extend([setup_config, pyproject_config])
for config in config_files:
if config.zest_releaser_config() is not None:
zest_config = config.zest_releaser_config()
assert isinstance(zest_config, dict)
Expand All @@ -298,7 +327,10 @@ def load_configs(self, pypirc_config_filename=DIST_CONFIG_FILE):
self.hooks_filename = config.config_filename
self.config = combined_config

def __init__(self, pypirc_config_filename=DIST_CONFIG_FILE):
def __init__(
self, pypirc_config_filename=DIST_CONFIG_FILE, omit_package_config_in_test=False
):
self.omit_package_config_in_test = omit_package_config_in_test
self.load_configs(pypirc_config_filename=pypirc_config_filename)

def want_release(self):
Expand Down
5 changes: 5 additions & 0 deletions zest/releaser/tests/baserelease.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ Change to a git dir:
>>> import os
>>> os.chdir(gitsourcedir)

We need to set test mode, to avoid reading ~/.pypirc::

>>> from zest.releaser import utils
>>> utils.TESTMODE = True

Init the Basereleaser, which is otherwise only used as a base class.

>>> from zest.releaser import baserelease
Expand Down
6 changes: 0 additions & 6 deletions zest/releaser/tests/functional-git.txt
Original file line number Diff line number Diff line change
Expand Up @@ -123,17 +123,11 @@ And the postrelease script ups the version:
Our reply: <ENTER>
Question: OK to push commits to the server? (Y/n)?
Our reply: n

The commit will contain an extra message with in this case a hint for
Travis to skip the Continuous Integration build, because our pypirc
has asked this with the extra-message option::

>>> from zest.releaser import lasttaglog
>>> lasttaglog.main()
git log...
Back to development: 0.2
<BLANKLINE>
[ci skip]...

The changelog and setup.py are at 0.2 and indicate dev mode:

Expand Down
20 changes: 6 additions & 14 deletions zest/releaser/tests/pypi.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,6 @@ There are two styles of ``.pypirc`` files. The old one just for pypi:
[server-login]
username:pipo_de_clown
password:asjemenou
<BLANKLINE>
[zest.releaser]
extra-message = [ci skip]
prefix-message = [TAG]
>>> pypiconfig = pypi.PypiConfig(config_filename=pypirc_old)
>>> pypiconfig.distutils_servers()
['pypi']
Expand Down Expand Up @@ -67,10 +63,6 @@ And the new format that allows multiple uploads:
repository:http://my.company/products
username:user
password:password
<BLANKLINE>
[zest.releaser]
extra-message = [ci skip]
prefix-message = [TAG]
>>> pypiconfig = pypi.PypiConfig(config_filename=pypirc_new)
>>> from pprint import pprint
>>> pprint(sorted(pypiconfig.distutils_servers()))
Expand Down Expand Up @@ -164,23 +156,23 @@ If the package is installed, we set a constant:
>>> USE_WHEEL
True

We try to read a [zest.releaser] section, either in pypirc or
setup.cfg and check for a ``create-wheel`` option. In this case we
explicitly disable checking for a setup.cfg, because when running the
We try to read a [zest.releaser] section, in pypirc, setup.cfg or
pyproject.toml and check for a ``create-wheel`` option. In this case we
explicitly disable checking for the files in the package, because when running the
tests with ``tox`` the current directory is the base directory of
zest.releaser, which now contains a setup.cfg.

We can ask for the result like this, which by default is True:

>>> zestreleaserconfig = pypi.ZestReleaserConfig(pypirc_config_filename=pypirc_both)
>>> zestreleaserconfig = pypi.ZestReleaserConfig(pypirc_config_filename=pypirc_both, omit_package_config_in_test=True)
>>> zestreleaserconfig.create_wheel()
True

We can also specify to not create the wheel, even when (universal) wheels could be created:

>>> pypirc_yes_release = pkg_resources.resource_filename(
>>> pypirc_no_create = pkg_resources.resource_filename(
... 'zest.releaser.tests', 'pypirc_universal_nocreate.txt')
>>> zestreleaserconfig = pypi.ZestReleaserConfig(pypirc_config_filename=pypirc_yes_release)
>>> zestreleaserconfig = pypi.ZestReleaserConfig(pypirc_config_filename=pypirc_no_create, omit_package_config_in_test=True)
>>> zestreleaserconfig.create_wheel()
False

Expand Down
4 changes: 0 additions & 4 deletions zest/releaser/tests/pypirc_new.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,3 @@ password:password
repository:http://my.company/products
username:user
password:password

[zest.releaser]
extra-message = [ci skip]
prefix-message = [TAG]
4 changes: 0 additions & 4 deletions zest/releaser/tests/pypirc_old.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
[server-login]
username:pipo_de_clown
password:asjemenou

[zest.releaser]
extra-message = [ci skip]
prefix-message = [TAG]
11 changes: 10 additions & 1 deletion zest/releaser/vcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import logging
import os
import pkg_resources
import re
import sys

Expand Down Expand Up @@ -66,7 +67,15 @@ def __init__(self, reporoot=None):
self.reporoot = reporoot
# Determine relative path from root of repo.
self.relative_path_in_repo = os.path.relpath(self.workingdir, reporoot)
self.zest_releaser_config = pypi.ZestReleaserConfig()
if utils.TESTMODE:
pypirc_old = pkg_resources.resource_filename(
"zest.releaser.tests", "pypirc_old.txt"
)
self.zest_releaser_config = pypi.ZestReleaserConfig(
pypirc_config_filename=pypirc_old
)
else:
self.zest_releaser_config = pypi.ZestReleaserConfig()
self.fallback_encoding = self.zest_releaser_config.encoding()

def __repr__(self):
Expand Down

0 comments on commit fb76b21

Please sign in to comment.