Browse Source

fix MANIFEST.in rendering if readme file is outside of the package directory

shut-new-model
Niklas Rosenstein 9 months ago
parent
commit
3cbc5fa6a2
No known key found for this signature in database GPG Key ID: 6D269B33D25F6C6
1 changed files with 35 additions and 16 deletions
  1. + 35
    - 16
      src/shut/renderers/setuptools.py

+ 35
- 16
src/shut/renderers/setuptools.py

@ -19,6 +19,7 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
import collections
import contextlib
import os
import re
@ -38,6 +39,8 @@ GENERATED_FILE_REMARK = '''
# For more information about Shut, check out https://pypi.org/project/shut/
'''.strip() + '\n'
_ReadmeStatus = collections.namedtuple('ReadmeStatus', 'path,runtime_path,outside')
def _normpath(x):
return os.path.normpath(x).replace(os.sep, '/')
@ -299,18 +302,10 @@ class SetuptoolsRenderer(Renderer[PackageModel]):
def _render_requirements(self, fp: TextIO, target: str, requirements: List[Requirement]):
fp.write('{} = {}\n'.format(target, self._format_reqs(requirements)))
def _render_readme_code(self, fp: TextIO, package: PackageModel) -> Tuple[Optional[str], Optional[str]]:
def _get_readme_status(self, package: PackageModel) -> Optional[_ReadmeStatus]:
"""
Renders code for the setup.py file, creating a `long_description` variable. If
a readme file is present or explicitly specified in *package*, that readme file
will be read for the setup.
The readme file may be locatated outside of the packages' directory. In this case,
the setup.py file will temporarily copy it into the package root directory during
the setup.
Returns the Python expression to pass into the `long_description` field of the
#setuptools.setup() call.
Returns some information on the readme for a package. The readme can be located outside
of the package directory, but that needs to be handled special in various cases.
"""
readme = package.get_readme_file()
@ -329,16 +324,37 @@ class SetuptoolsRenderer(Renderer[PackageModel]):
else:
readme_relative_path = os.path.basename(readme)
fp.write('\nreadme_file = {!r}\n'.format(readme_relative_path))
return _ReadmeStatus(readme, readme_relative_path, not is_inside)
if not is_inside:
def _render_readme_code(self, fp: TextIO, package: PackageModel) -> Tuple[Optional[str], Optional[str]]:
"""
Renders code for the setup.py file, creating a `long_description` variable. If
a readme file is present or explicitly specified in *package*, that readme file
will be read for the setup.
The readme file may be locatated outside of the packages' directory. In this case,
the setup.py file will temporarily copy it into the package root directory during
the setup.
Returns the Python expression to pass into the `long_description` field of the
#setuptools.setup() call.
"""
readme = self._get_readme_status(package)
if not readme:
return None, None
fp.write('\nreadme_file = {!r}\n'.format(readme.runtime_path))
if readme.outside:
# Copy the relative README file if it exists.
fp.write(textwrap.dedent('''
source_readme_file = {!r}
if not os.path.isfile(readme_file) and os.path.isfile(source_readme_file):
import shutil; shutil.copyfile(source_readme_file, readme_file)
import atexit; atexit.register(lambda: os.remove(readme_file))
''').format(readme).lstrip())
''').format(readme.path).lstrip())
# Read the contents of the file into the "long_description" variable.
fp.write(textwrap.dedent('''
@ -350,7 +366,7 @@ class SetuptoolsRenderer(Renderer[PackageModel]):
long_description = None
''').lstrip())
return readme, 'long_description'
return readme.path, 'long_description'
def _render_manifest_in(self, fp: TextIO, current: TextIO, package: PackageModel) -> None:
"""
@ -360,11 +376,14 @@ class SetuptoolsRenderer(Renderer[PackageModel]):
files = [
package.filename,
package.get_readme_file(),
package.get_license_file(),
package.get_py_typed_file(),
]
readme = self._get_readme_status(package)
if readme:
files.append(readme.runtime_path)
manifest = [
os.path.relpath(f, package.get_directory())
for f in files

Loading…
Cancel
Save