Gael Pasgrimaud avatar Gael Pasgrimaud committed c8dfb3c

Allow to have more than one file in description-file. Also check that those files are added to MANIFEST

Comments (0)

Files changed (4)

distutils2/command/sdist.py

 from distutils2.command import get_command_names
 from distutils2.command.cmd import Command
 from distutils2.errors import (DistutilsPlatformError, DistutilsOptionError,
-                               DistutilsTemplateError, DistutilsModuleError)
+                               DistutilsTemplateError, DistutilsModuleError,
+                               DistutilsFileError)
 from distutils2.manifest import Manifest
 from distutils2 import logger
 from distutils2.util import convert_path, resolve_name
             logger.warn("no files to distribute -- empty manifest?")
         else:
             logger.info(msg)
+
+        for file in self.distribution.metadata.requires_files:
+            if file not in files:
+                msg = "'%s' must be included explicitly extra-files metadata" % file
+                raise DistutilsFileError(msg)
+
         for file in files:
             if not os.path.isfile(file):
                 logger.warn("'%s' not a regular file -- skipping" % file)

distutils2/config.py

                                "mutually exclusive")
                         raise DistutilsOptionError(msg)
 
-                    f = open(value)    # will raise if file not found
-                    try:
-                        value = f.read()
-                    finally:
-                        f.close()
+                    if isinstance(value, list):
+                        filenames = value
+                    else:
+                        filenames = value.split()
+
+                    # concatenate each files
+                    value = ''
+                    for filename in filenames:
+                        f = open(filename)    # will raise if file not found
+                        try:
+                            value += f.read().strip() + '\n'
+                        finally:
+                            f.close()
+                        # add filename as a required file
+                        if filename not in metadata.requires_files:
+                            metadata.requires_files.append(filename)
+                    value = value.strip()
                     key = 'description'
 
                 if metadata.is_metadata_field(key):

distutils2/metadata.py

         self._fields = {}
         self.display_warnings = display_warnings
         self.version = None
+        self.requires_files = []
         self.docutils_support = _HAS_DOCUTILS
         self.platform_dependent = platform_dependent
         self.execution_context = execution_context

distutils2/tests/test_config.py

 from StringIO import StringIO
 
 from distutils2.tests import unittest, support, run_unittest
+from distutils2.command.sdist import sdist
+from distutils2.errors import DistutilsFileError
 
 
 SETUP_CFG = """
 maintainer = Éric Araujo
 maintainer_email = merwok@netwok.org
 summary = A sample project demonstrating distutils2 packaging
-description-file = README
+description-file = %(description-file)s
 keywords = distutils2, packaging, sample project
 
 classifier =
   config = cfg/data.cfg
   /etc/init.d = init-script
 
+extra_files = %(extra-files)s
+
 # Replaces MANIFEST.in
 sdist_extra =
   include THANKS HACKING
         self.addCleanup(setattr, sys, 'stderr', sys.stderr)
         self.addCleanup(os.chdir, os.getcwd())
 
-    def test_config(self):
-        tempdir = self.mkdtemp()
-        os.chdir(tempdir)
-        self.write_file('setup.cfg', SETUP_CFG)
-        self.write_file('README', 'yeah')
+    def write_setup(self, kwargs=None):
+        opts = {'description-file': 'README', 'extra-files':''}
+        if kwargs:
+            opts.update(kwargs)
+        self.write_file('setup.cfg', SETUP_CFG % opts)
 
-        # try to load the metadata now
+    def run_setup(self, *args):
+        # run setup with args
         sys.stdout = StringIO()
-        sys.argv[:] = ['setup.py', '--version']
+        sys.argv[:] = [''] + list(args)
         old_sys = sys.argv[:]
-
         try:
             from distutils2.run import commands_main
             dist = commands_main()
         finally:
             sys.argv[:] = old_sys
+        return dist
+
+    def test_config(self):
+        tempdir = self.mkdtemp()
+        os.chdir(tempdir)
+        self.write_setup()
+        self.write_file('README', 'yeah')
+
+        # try to load the metadata now
+        dist = self.run_setup('--version')
 
         # sanity check
         self.assertEqual(sys.stdout.getvalue(), '0.6.4.dev1' + os.linesep)
         d = new_compiler(compiler='d')
         self.assertEqual(d.description, 'D Compiler')
 
+
+    def test_multiple_description_file(self):
+        tempdir = self.mkdtemp()
+        os.chdir(tempdir)
+
+        self.write_setup({'description-file': 'README  CHANGES'})
+        self.write_file('README', 'yeah')
+        self.write_file('CHANGES', 'changelog2')
+        dist = self.run_setup('--version')
+        self.assertEqual(dist.metadata.requires_files, ['README', 'CHANGES'])
+
+    def test_multiline_description_file(self):
+        tempdir = self.mkdtemp()
+        os.chdir(tempdir)
+
+        self.write_setup({'description-file': 'README\n  CHANGES'})
+        self.write_file('README', 'yeah')
+        self.write_file('CHANGES', 'changelog')
+        dist = self.run_setup('--version')
+        self.assertEqual(dist.metadata['description'], 'yeah\nchangelog')
+        self.assertEqual(dist.metadata.requires_files, ['README', 'CHANGES'])
+
+    def test_metadata_requires_description_files_missing(self):
+        tempdir = self.mkdtemp()
+        os.chdir(tempdir)
+        self.write_setup({'description-file': 'README\n  README2'})
+        self.write_file('README', 'yeah')
+        self.write_file('README2', 'yeah')
+        self.write_file('haven.py', '#')
+        self.write_file('script1.py', '#')
+        os.mkdir('scripts')
+        self.write_file(os.path.join('scripts', 'find-coconuts'), '#')
+        os.mkdir('bin')
+        self.write_file(os.path.join('bin', 'taunt'), '#')
+
+        for pkg in ('one', 'src', 'src2'):
+            os.mkdir(pkg)
+            self.write_file(os.path.join(pkg, '__init__.py'), '#')
+
+        dist = self.run_setup('--version')
+        cmd = sdist(dist)
+        cmd.finalize_options()
+        cmd.get_file_list()
+        self.assertRaises(DistutilsFileError, cmd.make_distribution)
+
+    def test_metadata_requires_description_files(self):
+        tempdir = self.mkdtemp()
+        os.chdir(tempdir)
+        self.write_setup({'description-file': 'README\n  README2', 'extra-files':'\n  README2'})
+        self.write_file('README', 'yeah')
+        self.write_file('README2', 'yeah')
+        self.write_file('haven.py', '#')
+        self.write_file('script1.py', '#')
+        os.mkdir('scripts')
+        self.write_file(os.path.join('scripts', 'find-coconuts'), '#')
+        os.mkdir('bin')
+        self.write_file(os.path.join('bin', 'taunt'), '#')
+
+        for pkg in ('one', 'src', 'src2'):
+            os.mkdir(pkg)
+            self.write_file(os.path.join(pkg, '__init__.py'), '#')
+
+        dist = self.run_setup('--version')
+        cmd = sdist(dist)
+        cmd.finalize_options()
+        cmd.get_file_list()
+        cmd.make_distribution()
+        self.assertIn('README\nREADME2\n', open('MANIFEST').read())
+
+
     def test_sub_commands(self):
         tempdir = self.mkdtemp()
         os.chdir(tempdir)
-        self.write_file('setup.cfg', SETUP_CFG)
+        self.write_setup()
         self.write_file('README', 'yeah')
         self.write_file('haven.py', '#')
         self.write_file('script1.py', '#')
             self.write_file(os.path.join(pkg, '__init__.py'), '#')
 
         # try to run the install command to see if foo is called
-        sys.stdout = sys.stderr = StringIO()
-        sys.argv[:] = ['', 'install_dist']
-        old_sys = sys.argv[:]
-        try:
-            from distutils2.run import main
-            dist = main()
-        finally:
-            sys.argv[:] = old_sys
+        dist = self.run_setup('install_dist')
 
         self.assertEqual(dist.foo_was_here, 1)
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.