diff --git a/lib/vsc/install/shared_setup.py b/lib/vsc/install/shared_setup.py index 446e89d0..3a2b8a5e 100644 --- a/lib/vsc/install/shared_setup.py +++ b/lib/vsc/install/shared_setup.py @@ -169,7 +169,7 @@ def _log(self, level, msg, args): RELOAD_VSC_MODS = False -VERSION = '0.17.24' +VERSION = '0.17.25' log.info('This is (based on) vsc.install.shared_setup %s' % VERSION) log.info('(using setuptools version %s located at %s)' % (setuptools.__version__, setuptools.__file__)) @@ -207,7 +207,16 @@ def _log(self, level, msg, args): # location of README file -README = 'README.md' +README_BASE = ['README'] +# see https://packaging.python.org/guides/making-a-pypi-friendly-readme/ +README_EXT = ('.md', '.rst', '.txt', '') +README_TYPES = { + '.md': 'text/markdown', + '.rst': 'text/x-rst', + '.txt': 'text/plain', + '': 'text/plain', # fallback in case README file has no extension +} +README = ['%s%s' % (base, ext) for base in README_BASE for ext in README_EXT] # location of LICENSE file LICENSE = 'LICENSE' @@ -657,7 +666,7 @@ def make_release_tree(self, base_dir, files): self._add_shared_setup(base_dir) # Add mandatory files - for fn in [LICENSE, README]: + for fn in [LICENSE] + README: self.copy_file(os.path.join(self.setup.REPO_BASE_DIR, fn), os.path.join(base_dir, fn)) class vsc_sdist_rpm(vsc_sdist): @@ -1331,6 +1340,25 @@ def get_license(self, license_name=None): log.info("Found license name %s and classifier %s", lic_short, data[1]) return lic_short, data[1] + def locate_readme(self): + """ + Returns path to README file in the package from allowed options in README global + The highest option in README global is preferred + """ + readme = None + + for readme_path in [os.path.join(self.REPO_BASE_DIR, readme) for readme in README]: + if os.path.exists(readme_path): + readme = readme_path + break + + # README is required + if readme is None: + raise Exception('README is missing (was looking for: %s)' % ", ".join(README)) + + log.info('found README file at %s' % readme) + return readme + def parse_target(self, target, urltemplate=None): """ Add some fields @@ -1388,17 +1416,23 @@ def parse_target(self, target, urltemplate=None): if 'github' in urltemplate: new_target['download_url'] = "%s/tarball/master" % new_target['url'] - # Readme are required - readme = os.path.join(self.REPO_BASE_DIR, README) - if not os.path.exists(readme): - raise Exception('README is missing (was looking for %s)' % readme) + # Use description file from target and remove attribute (not needed any more) + readme_file = target.pop('description_file', None) + # set description from README vsc_description = target.pop('vsc_description', True) if vsc_description: + + if not readme_file: + # locate the README file + readme_file = self.locate_readme() + if 'long_description' in target: - log.info(('Going to ignore the provided long_descripton.' - 'Set it in the %s or disable vsc_description') % README) - readmetxt = _read(readme) + log.warn(('Ignoring the provided long_descripton.' + 'Please set it in the %s or disable vsc_description') % os.path.basename(readme_file)) + del(target['long_description']) + + readmetxt = _read(readme_file) # look for description block, read text until double empty line or new block # allow 'words with === on next line' or comment-like block '# title' @@ -1415,24 +1449,16 @@ def parse_target(self, target, urltemplate=None): descr = re.sub(r'\s+', ' ', descr) # squash whitespace except IndexError: raise Exception('Could not find a Description block in the README %s to create the long description' % - readme) + readme_file) log.info('using long_description %s' % descr) new_target['description'] = descr # summary in PKG-INFO new_target['long_description'] = readmetxt # description in PKG-INFO - readme_ext = os.path.splitext(readme)[-1] - # see https://packaging.python.org/guides/making-a-pypi-friendly-readme/ - readme_content_types = { - '.md': 'text/markdown', - '.rst': 'text/x-rst', - '.txt': 'text/plain', - # fallback in case README file has no extension - '': 'text/plain', - } - if readme_ext in readme_content_types: - new_target['long_description_content_type'] = readme_content_types[readme_ext] + readme_ext = os.path.splitext(readme_file)[-1] + if readme_ext in README_TYPES: + new_target['long_description_content_type'] = README_TYPES[readme_ext] else: - raise Exception("Failed to derive content type for README file '%s' based on extension" % readme) + raise Exception("Failed to derive content type for README file '%s' based on extension" % readme_file) vsc_scripts = target.pop('vsc_scripts', True) if vsc_scripts: @@ -1632,7 +1658,9 @@ def build_setup_cfg_for_bdist_rpm(target): txt.extend(["build_requires = %s" % (klass.sanitize(target['setup_requires']))]) # add metadata - txt += ['', '[metadata]', '', 'description-file = %s' % README, ''] + if 'description_file' in target: + description_file = os.path.basename(target['description_file']) + txt += ['', '[metadata]', '', 'description-file = %s' % description_file, ''] setup_cfg.write("\n".join(txt+[''])) setup_cfg.close() @@ -1682,6 +1710,9 @@ def action_target(self, target, setupfn=None, extra_sdist=None, urltemplate=None if do_cleanup: self.cleanup() + # add location of README to target + target['description_file'] = self.locate_readme() + self.prepare_rpm(target) new_target = self.parse_target(target, urltemplate) diff --git a/test/shared_setup.py b/test/shared_setup.py index 4027e4b4..d61f32ba 100644 --- a/test/shared_setup.py +++ b/test/shared_setup.py @@ -313,7 +313,10 @@ def read_setup_cfg(): os.chdir(self.tmpdir) # test with minimal target - vsc_setup.build_setup_cfg_for_bdist_rpm({}) + target = { + 'description_file': 'README.md', + } + vsc_setup.build_setup_cfg_for_bdist_rpm(target) expected = '\n'.join([ '[bdist_rpm]', '', @@ -325,6 +328,7 @@ def read_setup_cfg(): # realistic target target = { + 'description_file': 'README.md', 'install_requires': ['vsc-base >= 3.1.0', 'vsc-ldap', 'requests', 'foobar < 1.0'], 'setup_requires': ['vsc-install >= 0.17.11'], }