blob: 655e50dcfc2f84dc76b2fa83f9bf1e16cc2a281b [file] [log] [blame]
Benjamin Peterson960cf0f2009-01-09 04:11:44 +00001"""Tests for distutils.command.sdist."""
2import os
3import unittest
4import shutil
5import zipfile
6from os.path import join
Tarek Ziadé0302cf52009-01-26 17:23:20 +00007import sys
Tarek Ziadéc1375d52009-02-14 14:35:51 +00008import tempfile
Tarek Ziadé5af55c62009-05-16 16:52:13 +00009import warnings
Benjamin Peterson960cf0f2009-01-09 04:11:44 +000010
Éric Araujob344dd02011-02-02 21:38:37 +000011from test.support import captured_stdout, check_warnings, run_unittest
Tarek Ziadéaec039a2009-05-14 12:45:48 +000012
Éric Araujob344dd02011-02-02 21:38:37 +000013from distutils.command.sdist import sdist, show_formats
Benjamin Peterson960cf0f2009-01-09 04:11:44 +000014from distutils.core import Distribution
15from distutils.tests.test_config import PyPIRCCommandTestCase
Tarek Ziadéda0dc2e2009-05-14 15:21:26 +000016from distutils.errors import DistutilsExecError, DistutilsOptionError
Tarek Ziadéb18b9362009-01-29 23:54:06 +000017from distutils.spawn import find_executable
Tarek Ziadé0d0506e2009-02-16 21:49:12 +000018from distutils.tests import support
Tarek Ziadé5af55c62009-05-16 16:52:13 +000019from distutils.log import WARN
Tarek Ziadéaec039a2009-05-14 12:45:48 +000020from distutils.archive_util import ARCHIVE_FORMATS
Benjamin Peterson960cf0f2009-01-09 04:11:44 +000021
Benjamin Peterson960cf0f2009-01-09 04:11:44 +000022SETUP_PY = """
23from distutils.core import setup
24import somecode
25
26setup(name='fake')
27"""
28
Tarek Ziadé0d0506e2009-02-16 21:49:12 +000029MANIFEST = """\
Éric Araujo60a95b72010-08-14 02:36:26 +000030# file GENERATED by distutils, do NOT edit
Tarek Ziadé0d0506e2009-02-16 21:49:12 +000031README
Tarek Ziadé14d34a02009-02-17 23:10:18 +000032inroot.txt
Tarek Ziadé0d0506e2009-02-16 21:49:12 +000033setup.py
Tarek Ziadéde27e482009-02-16 21:51:13 +000034data%(sep)sdata.dt
35scripts%(sep)sscript.py
Tarek Ziadéa30337a2009-02-17 09:47:25 +000036some%(sep)sfile.txt
37some%(sep)sother_file.txt
Tarek Ziadéde27e482009-02-16 21:51:13 +000038somecode%(sep)s__init__.py
39somecode%(sep)sdoc.dat
40somecode%(sep)sdoc.txt
Benjamin Peterson960cf0f2009-01-09 04:11:44 +000041"""
42
Tarek Ziadé5af55c62009-05-16 16:52:13 +000043class SDistTestCase(PyPIRCCommandTestCase):
Benjamin Peterson960cf0f2009-01-09 04:11:44 +000044
45 def setUp(self):
Tarek Ziadéc1375d52009-02-14 14:35:51 +000046 # PyPIRCCommandTestCase creates a temp dir already
47 # and put it in self.tmp_dir
Tarek Ziadé5af55c62009-05-16 16:52:13 +000048 super(SDistTestCase, self).setUp()
Tarek Ziadéc1375d52009-02-14 14:35:51 +000049 # setting up an environment
Benjamin Peterson960cf0f2009-01-09 04:11:44 +000050 self.old_path = os.getcwd()
Tarek Ziadéc1375d52009-02-14 14:35:51 +000051 os.mkdir(join(self.tmp_dir, 'somecode'))
52 os.mkdir(join(self.tmp_dir, 'dist'))
Tarek Ziadé0d0506e2009-02-16 21:49:12 +000053 # a package, and a README
54 self.write_file((self.tmp_dir, 'README'), 'xxx')
55 self.write_file((self.tmp_dir, 'somecode', '__init__.py'), '#')
56 self.write_file((self.tmp_dir, 'setup.py'), SETUP_PY)
Tarek Ziadéc1375d52009-02-14 14:35:51 +000057 os.chdir(self.tmp_dir)
Benjamin Peterson960cf0f2009-01-09 04:11:44 +000058
59 def tearDown(self):
Tarek Ziadéc1375d52009-02-14 14:35:51 +000060 # back to normal
Benjamin Peterson960cf0f2009-01-09 04:11:44 +000061 os.chdir(self.old_path)
Tarek Ziadé5af55c62009-05-16 16:52:13 +000062 super(SDistTestCase, self).tearDown()
Benjamin Peterson960cf0f2009-01-09 04:11:44 +000063
Tarek Ziadé0d0506e2009-02-16 21:49:12 +000064 def get_cmd(self, metadata=None):
65 """Returns a cmd"""
66 if metadata is None:
67 metadata = {'name': 'fake', 'version': '1.0',
68 'url': 'xxx', 'author': 'xxx',
69 'author_email': 'xxx'}
70 dist = Distribution(metadata)
71 dist.script_name = 'setup.py'
72 dist.packages = ['somecode']
73 dist.include_package_data = True
74 cmd = sdist(dist)
75 cmd.dist_dir = 'dist'
76 def _warn(*args):
77 pass
78 cmd.warn = _warn
79 return dist, cmd
Benjamin Peterson960cf0f2009-01-09 04:11:44 +000080
81 def test_prune_file_list(self):
82 # this test creates a package with some vcs dirs in it
83 # and launch sdist to make sure they get pruned
84 # on all systems
Benjamin Peterson960cf0f2009-01-09 04:11:44 +000085
86 # creating VCS directories with some files in them
Tarek Ziadéc1375d52009-02-14 14:35:51 +000087 os.mkdir(join(self.tmp_dir, 'somecode', '.svn'))
Tarek Ziadé0d0506e2009-02-16 21:49:12 +000088 self.write_file((self.tmp_dir, 'somecode', '.svn', 'ok.py'), 'xxx')
Benjamin Peterson960cf0f2009-01-09 04:11:44 +000089
Tarek Ziadéc1375d52009-02-14 14:35:51 +000090 os.mkdir(join(self.tmp_dir, 'somecode', '.hg'))
Tarek Ziadé0d0506e2009-02-16 21:49:12 +000091 self.write_file((self.tmp_dir, 'somecode', '.hg',
Benjamin Peterson960cf0f2009-01-09 04:11:44 +000092 'ok'), 'xxx')
93
Tarek Ziadéc1375d52009-02-14 14:35:51 +000094 os.mkdir(join(self.tmp_dir, 'somecode', '.git'))
Tarek Ziadé0d0506e2009-02-16 21:49:12 +000095 self.write_file((self.tmp_dir, 'somecode', '.git',
Benjamin Peterson960cf0f2009-01-09 04:11:44 +000096 'ok'), 'xxx')
97
Benjamin Peterson960cf0f2009-01-09 04:11:44 +000098 # now building a sdist
Tarek Ziadé0d0506e2009-02-16 21:49:12 +000099 dist, cmd = self.get_cmd()
Benjamin Peterson960cf0f2009-01-09 04:11:44 +0000100
101 # zip is available universally
102 # (tar might not be installed under win32)
103 cmd.formats = ['zip']
Tarek Ziadé0d0506e2009-02-16 21:49:12 +0000104
105 cmd.ensure_finalized()
Benjamin Peterson960cf0f2009-01-09 04:11:44 +0000106 cmd.run()
107
108 # now let's check what we have
Tarek Ziadéc1375d52009-02-14 14:35:51 +0000109 dist_folder = join(self.tmp_dir, 'dist')
Benjamin Peterson960cf0f2009-01-09 04:11:44 +0000110 files = os.listdir(dist_folder)
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000111 self.assertEqual(files, ['fake-1.0.zip'])
Benjamin Peterson960cf0f2009-01-09 04:11:44 +0000112
113 zip_file = zipfile.ZipFile(join(dist_folder, 'fake-1.0.zip'))
114 try:
115 content = zip_file.namelist()
116 finally:
117 zip_file.close()
118
119 # making sure everything has been pruned correctly
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000120 self.assertEqual(len(content), 4)
Benjamin Peterson960cf0f2009-01-09 04:11:44 +0000121
Tarek Ziadé0302cf52009-01-26 17:23:20 +0000122 def test_make_distribution(self):
123
Tarek Ziadéb18b9362009-01-29 23:54:06 +0000124 # check if tar and gzip are installed
125 if (find_executable('tar') is None or
126 find_executable('gzip') is None):
127 return
Tarek Ziadé0302cf52009-01-26 17:23:20 +0000128
Tarek Ziadé0302cf52009-01-26 17:23:20 +0000129 # now building a sdist
Tarek Ziadé0d0506e2009-02-16 21:49:12 +0000130 dist, cmd = self.get_cmd()
Tarek Ziadé0302cf52009-01-26 17:23:20 +0000131
132 # creating a gztar then a tar
133 cmd.formats = ['gztar', 'tar']
Tarek Ziadé0d0506e2009-02-16 21:49:12 +0000134 cmd.ensure_finalized()
Tarek Ziadé0302cf52009-01-26 17:23:20 +0000135 cmd.run()
136
137 # making sure we have two files
Tarek Ziadéc1375d52009-02-14 14:35:51 +0000138 dist_folder = join(self.tmp_dir, 'dist')
Tarek Ziadé0302cf52009-01-26 17:23:20 +0000139 result = os.listdir(dist_folder)
140 result.sort()
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000141 self.assertEqual(result, ['fake-1.0.tar', 'fake-1.0.tar.gz'] )
Tarek Ziadé0302cf52009-01-26 17:23:20 +0000142
143 os.remove(join(dist_folder, 'fake-1.0.tar'))
144 os.remove(join(dist_folder, 'fake-1.0.tar.gz'))
145
146 # now trying a tar then a gztar
147 cmd.formats = ['tar', 'gztar']
Tarek Ziadé0d0506e2009-02-16 21:49:12 +0000148
149 cmd.ensure_finalized()
Tarek Ziadé0302cf52009-01-26 17:23:20 +0000150 cmd.run()
151
152 result = os.listdir(dist_folder)
153 result.sort()
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000154 self.assertEqual(result, ['fake-1.0.tar', 'fake-1.0.tar.gz'])
Tarek Ziadé0302cf52009-01-26 17:23:20 +0000155
Tarek Ziadé0d0506e2009-02-16 21:49:12 +0000156 def test_add_defaults(self):
157
158 # http://bugs.python.org/issue2279
159
160 # add_default should also include
161 # data_files and package_data
162 dist, cmd = self.get_cmd()
163
164 # filling data_files by pointing files
165 # in package_data
166 dist.package_data = {'': ['*.cfg', '*.dat'],
167 'somecode': ['*.txt']}
168 self.write_file((self.tmp_dir, 'somecode', 'doc.txt'), '#')
169 self.write_file((self.tmp_dir, 'somecode', 'doc.dat'), '#')
170
171 # adding some data in data_files
172 data_dir = join(self.tmp_dir, 'data')
173 os.mkdir(data_dir)
174 self.write_file((data_dir, 'data.dt'), '#')
Tarek Ziadéa30337a2009-02-17 09:47:25 +0000175 some_dir = join(self.tmp_dir, 'some')
176 os.mkdir(some_dir)
Tarek Ziadé14d34a02009-02-17 23:10:18 +0000177 self.write_file((self.tmp_dir, 'inroot.txt'), '#')
Tarek Ziadéa30337a2009-02-17 09:47:25 +0000178 self.write_file((some_dir, 'file.txt'), '#')
179 self.write_file((some_dir, 'other_file.txt'), '#')
180
Tarek Ziadé14d34a02009-02-17 23:10:18 +0000181 dist.data_files = [('data', ['data/data.dt',
182 'inroot.txt',
183 'notexisting']),
Tarek Ziadéa30337a2009-02-17 09:47:25 +0000184 'some/file.txt',
185 'some/other_file.txt']
Tarek Ziadé0d0506e2009-02-16 21:49:12 +0000186
187 # adding a script
188 script_dir = join(self.tmp_dir, 'scripts')
189 os.mkdir(script_dir)
190 self.write_file((script_dir, 'script.py'), '#')
191 dist.scripts = [join('scripts', 'script.py')]
192
Tarek Ziadé0d0506e2009-02-16 21:49:12 +0000193 cmd.formats = ['zip']
194 cmd.use_defaults = True
195
196 cmd.ensure_finalized()
197 cmd.run()
198
199 # now let's check what we have
200 dist_folder = join(self.tmp_dir, 'dist')
201 files = os.listdir(dist_folder)
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000202 self.assertEqual(files, ['fake-1.0.zip'])
Tarek Ziadé0d0506e2009-02-16 21:49:12 +0000203
204 zip_file = zipfile.ZipFile(join(dist_folder, 'fake-1.0.zip'))
205 try:
206 content = zip_file.namelist()
207 finally:
208 zip_file.close()
209
210 # making sure everything was added
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000211 self.assertEqual(len(content), 11)
Tarek Ziadé0d0506e2009-02-16 21:49:12 +0000212
213 # checking the MANIFEST
Éric Araujoc6d7ead2010-11-06 02:58:56 +0000214 f = open(join(self.tmp_dir, 'MANIFEST'))
215 try:
216 manifest = f.read()
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000217 self.assertEqual(manifest, MANIFEST % {'sep': os.sep})
Éric Araujoc6d7ead2010-11-06 02:58:56 +0000218 finally:
219 f.close()
Tarek Ziadé0d0506e2009-02-16 21:49:12 +0000220
Tarek Ziadé5af55c62009-05-16 16:52:13 +0000221 def test_metadata_check_option(self):
222 # testing the `medata-check` option
223 dist, cmd = self.get_cmd(metadata={})
224
225 # this should raise some warnings !
226 # with the `check` subcommand
227 cmd.ensure_finalized()
228 cmd.run()
229 warnings = self.get_logs(WARN)
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000230 self.assertEqual(len(warnings), 2)
Tarek Ziadé5af55c62009-05-16 16:52:13 +0000231
232 # trying with a complete set of metadata
233 self.clear_logs()
234 dist, cmd = self.get_cmd()
235 cmd.ensure_finalized()
236 cmd.metadata_check = 0
237 cmd.run()
238 warnings = self.get_logs(WARN)
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000239 self.assertEqual(len(warnings), 0)
Tarek Ziadé5af55c62009-05-16 16:52:13 +0000240
241 def test_check_metadata_deprecated(self):
242 # makes sure make_metadata is deprecated
243 dist, cmd = self.get_cmd()
244 with check_warnings() as w:
245 warnings.simplefilter("always")
246 cmd.check_metadata()
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000247 self.assertEqual(len(w.warnings), 1)
Tarek Ziadé5af55c62009-05-16 16:52:13 +0000248
Tarek Ziadéaec039a2009-05-14 12:45:48 +0000249 def test_show_formats(self):
250 with captured_stdout() as stdout:
251 show_formats()
252
253 # the output should be a header line + one line per format
254 num_formats = len(ARCHIVE_FORMATS.keys())
255 output = [line for line in stdout.getvalue().split('\n')
256 if line.strip().startswith('--formats=')]
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000257 self.assertEqual(len(output), num_formats)
Tarek Ziadéaec039a2009-05-14 12:45:48 +0000258
Tarek Ziadéda0dc2e2009-05-14 15:21:26 +0000259 def test_finalize_options(self):
260
261 dist, cmd = self.get_cmd()
262 cmd.finalize_options()
263
264 # default options set by finalize
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000265 self.assertEqual(cmd.manifest, 'MANIFEST')
266 self.assertEqual(cmd.template, 'MANIFEST.in')
267 self.assertEqual(cmd.dist_dir, 'dist')
Tarek Ziadéda0dc2e2009-05-14 15:21:26 +0000268
269 # formats has to be a string splitable on (' ', ',') or
270 # a stringlist
271 cmd.formats = 1
272 self.assertRaises(DistutilsOptionError, cmd.finalize_options)
273 cmd.formats = ['zip']
274 cmd.finalize_options()
275
276 # formats has to be known
277 cmd.formats = 'supazipa'
278 self.assertRaises(DistutilsOptionError, cmd.finalize_options)
279
280
Tarek Ziadédd4671a2010-05-17 10:48:29 +0000281 def test_get_file_list(self):
282 # make sure MANIFEST is recalculated
283 dist, cmd = self.get_cmd()
284
285 # filling data_files by pointing files in package_data
286 dist.package_data = {'somecode': ['*.txt']}
287 self.write_file((self.tmp_dir, 'somecode', 'doc.txt'), '#')
288 cmd.ensure_finalized()
289 cmd.run()
290
291 f = open(cmd.manifest)
292 try:
293 manifest = [line.strip() for line in f.read().split('\n')
294 if line.strip() != '']
295 finally:
296 f.close()
297
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000298 self.assertEqual(len(manifest), 5)
Tarek Ziadédd4671a2010-05-17 10:48:29 +0000299
300 # adding a file
301 self.write_file((self.tmp_dir, 'somecode', 'doc2.txt'), '#')
302
303 # make sure build_py is reinitinialized, like a fresh run
304 build_py = dist.get_command_obj('build_py')
305 build_py.finalized = False
306 build_py.ensure_finalized()
307
308 cmd.run()
309
310 f = open(cmd.manifest)
311 try:
312 manifest2 = [line.strip() for line in f.read().split('\n')
313 if line.strip() != '']
314 finally:
315 f.close()
316
317 # do we have the new file in MANIFEST ?
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000318 self.assertEqual(len(manifest2), 6)
Tarek Ziadédd4671a2010-05-17 10:48:29 +0000319 self.assertIn('doc2.txt', manifest2[-1])
320
Éric Araujo60a95b72010-08-14 02:36:26 +0000321 def test_manifest_marker(self):
322 # check that autogenerated MANIFESTs have a marker
323 dist, cmd = self.get_cmd()
324 cmd.ensure_finalized()
325 cmd.run()
326
327 f = open(cmd.manifest)
328 try:
329 manifest = [line.strip() for line in f.read().split('\n')
330 if line.strip() != '']
331 finally:
332 f.close()
333
334 self.assertEqual(manifest[0],
335 '# file GENERATED by distutils, do NOT edit')
336
337 def test_manual_manifest(self):
338 # check that a MANIFEST without a marker is left alone
339 dist, cmd = self.get_cmd()
340 cmd.ensure_finalized()
341 self.write_file((self.tmp_dir, cmd.manifest), 'README.manual')
342 cmd.run()
343
344 f = open(cmd.manifest)
345 try:
346 manifest = [line.strip() for line in f.read().split('\n')
347 if line.strip() != '']
348 finally:
349 f.close()
350
351 self.assertEqual(manifest, ['README.manual'])
Tarek Ziadédd4671a2010-05-17 10:48:29 +0000352
Benjamin Peterson960cf0f2009-01-09 04:11:44 +0000353def test_suite():
Tarek Ziadé5af55c62009-05-16 16:52:13 +0000354 return unittest.makeSuite(SDistTestCase)
Benjamin Peterson960cf0f2009-01-09 04:11:44 +0000355
356if __name__ == "__main__":
Éric Araujob344dd02011-02-02 21:38:37 +0000357 run_unittest(test_suite())