Commit da668ff2 authored by Éric Araujo's avatar Éric Araujo

Use a marker in generated MANIFEST files, don't touch files without it. Fixes #8688.

parent e406ef41
...@@ -103,6 +103,10 @@ per line, regular files (or symlinks to them) only. If you do supply your own ...@@ -103,6 +103,10 @@ per line, regular files (or symlinks to them) only. If you do supply your own
:file:`MANIFEST`, you must specify everything: the default set of files :file:`MANIFEST`, you must specify everything: the default set of files
described above does not apply in this case. described above does not apply in this case.
.. versionadded:: 3.2
:file:`MANIFEST` files start with a comment indicated they are generated.
Files without this comment are not overwritten or removed.
The manifest template has one command per line, where each command specifies a The manifest template has one command per line, where each command specifies a
set of files to include or exclude from the source distribution. For an set of files to include or exclude from the source distribution. For an
example, again we turn to the Distutils' own manifest template:: example, again we turn to the Distutils' own manifest template::
...@@ -187,10 +191,6 @@ The normal course of operations for the :command:`sdist` command is as follows: ...@@ -187,10 +191,6 @@ The normal course of operations for the :command:`sdist` command is as follows:
* if neither :file:`MANIFEST` nor :file:`MANIFEST.in` exist, create a manifest * if neither :file:`MANIFEST` nor :file:`MANIFEST.in` exist, create a manifest
with just the default file set with just the default file set
* if either :file:`MANIFEST.in` or the setup script (:file:`setup.py`) are more
recent than :file:`MANIFEST`, recreate :file:`MANIFEST` by reading
:file:`MANIFEST.in`
* use the list of files now in :file:`MANIFEST` (either just generated or read * use the list of files now in :file:`MANIFEST` (either just generated or read
in) to create the source distribution archive(s) in) to create the source distribution archive(s)
...@@ -205,4 +205,7 @@ distribution:: ...@@ -205,4 +205,7 @@ distribution::
:option:`-o` is a shortcut for :option:`--manifest-only`. :option:`-o` is a shortcut for :option:`--manifest-only`.
.. versionchanged:: 3.2
An existing generated :file:`MANIFEST` will be regenerated without
:command:`sdist` comparing its modification time to the one of
:file:`MANIFEST.in` or :file:`setup.py`.
...@@ -335,8 +335,21 @@ class sdist(Command): ...@@ -335,8 +335,21 @@ class sdist(Command):
by 'add_defaults()' and 'read_template()') to the manifest file by 'add_defaults()' and 'read_template()') to the manifest file
named by 'self.manifest'. named by 'self.manifest'.
""" """
self.execute(file_util.write_file, if os.path.isfile(self.manifest):
(self.manifest, self.filelist.files), fp = open(self.manifest)
try:
first_line = fp.readline()
finally:
fp.close()
if first_line != '# file GENERATED by distutils, do NOT edit\n':
log.info("not writing to manually maintained "
"manifest file '%s'" % self.manifest)
return
content = self.filelist.files[:]
content.insert(0, '# file GENERATED by distutils, do NOT edit')
self.execute(file_util.write_file, (self.manifest, content),
"writing manifest file '%s'" % self.manifest) "writing manifest file '%s'" % self.manifest)
def read_manifest(self): def read_manifest(self):
......
...@@ -29,6 +29,7 @@ setup(name='fake') ...@@ -29,6 +29,7 @@ setup(name='fake')
""" """
MANIFEST = """\ MANIFEST = """\
# file GENERATED by distutils, do NOT edit
README README
inroot.txt inroot.txt
setup.py setup.py
...@@ -294,7 +295,7 @@ class SDistTestCase(PyPIRCCommandTestCase): ...@@ -294,7 +295,7 @@ class SDistTestCase(PyPIRCCommandTestCase):
finally: finally:
f.close() f.close()
self.assertEquals(len(manifest), 4) self.assertEquals(len(manifest), 5)
# adding a file # adding a file
self.write_file((self.tmp_dir, 'somecode', 'doc2.txt'), '#') self.write_file((self.tmp_dir, 'somecode', 'doc2.txt'), '#')
...@@ -314,9 +315,40 @@ class SDistTestCase(PyPIRCCommandTestCase): ...@@ -314,9 +315,40 @@ class SDistTestCase(PyPIRCCommandTestCase):
f.close() f.close()
# do we have the new file in MANIFEST ? # do we have the new file in MANIFEST ?
self.assertEquals(len(manifest2), 5) self.assertEquals(len(manifest2), 6)
self.assertIn('doc2.txt', manifest2[-1]) self.assertIn('doc2.txt', manifest2[-1])
def test_manifest_marker(self):
# check that autogenerated MANIFESTs have a marker
dist, cmd = self.get_cmd()
cmd.ensure_finalized()
cmd.run()
f = open(cmd.manifest)
try:
manifest = [line.strip() for line in f.read().split('\n')
if line.strip() != '']
finally:
f.close()
self.assertEqual(manifest[0],
'# file GENERATED by distutils, do NOT edit')
def test_manual_manifest(self):
# check that a MANIFEST without a marker is left alone
dist, cmd = self.get_cmd()
cmd.ensure_finalized()
self.write_file((self.tmp_dir, cmd.manifest), 'README.manual')
cmd.run()
f = open(cmd.manifest)
try:
manifest = [line.strip() for line in f.read().split('\n')
if line.strip() != '']
finally:
f.close()
self.assertEqual(manifest, ['README.manual'])
def test_suite(): def test_suite():
return unittest.makeSuite(SDistTestCase) return unittest.makeSuite(SDistTestCase)
......
...@@ -83,6 +83,10 @@ Extensions ...@@ -83,6 +83,10 @@ Extensions
Library Library
------- -------
- Issue #8688: MANIFEST files created by distutils now include a magic
comment indicating they are generated. Manually maintained MANIFESTs
without this marker will not be overwritten or removed.
- Issue #7467: when reading a file from a ZIP archive, its CRC is checked - Issue #7467: when reading a file from a ZIP archive, its CRC is checked
and a BadZipfile error is raised if it doesn't match (as used to be the and a BadZipfile error is raised if it doesn't match (as used to be the
case in Python 2.5 and earlier). case in Python 2.5 and earlier).
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment