blob: 73962d34f28d5ffb8fdc46f57145a6d9e5c062d2 [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 Araujo70ec44a2010-11-06 02:44:43 +000011from test.support import captured_stdout, check_warnings, run_unittest
Tarek Ziadéaec039a2009-05-14 12:45:48 +000012
Éric Araujo70ec44a2010-11-06 02:44:43 +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 Araujoda668ff2010-08-14 02:30:34 +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)
111 self.assertEquals(files, ['fake-1.0.zip'])
112
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
120 self.assertEquals(len(content), 4)
121
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()
141 self.assertEquals(result,
142 ['fake-1.0.tar', 'fake-1.0.tar.gz'] )
143
144 os.remove(join(dist_folder, 'fake-1.0.tar'))
145 os.remove(join(dist_folder, 'fake-1.0.tar.gz'))
146
147 # now trying a tar then a gztar
148 cmd.formats = ['tar', 'gztar']
Tarek Ziadé0d0506e2009-02-16 21:49:12 +0000149
150 cmd.ensure_finalized()
Tarek Ziadé0302cf52009-01-26 17:23:20 +0000151 cmd.run()
152
153 result = os.listdir(dist_folder)
154 result.sort()
155 self.assertEquals(result,
156 ['fake-1.0.tar', 'fake-1.0.tar.gz'])
157
Tarek Ziadé0d0506e2009-02-16 21:49:12 +0000158 def test_add_defaults(self):
159
160 # http://bugs.python.org/issue2279
161
162 # add_default should also include
163 # data_files and package_data
164 dist, cmd = self.get_cmd()
165
166 # filling data_files by pointing files
167 # in package_data
168 dist.package_data = {'': ['*.cfg', '*.dat'],
169 'somecode': ['*.txt']}
170 self.write_file((self.tmp_dir, 'somecode', 'doc.txt'), '#')
171 self.write_file((self.tmp_dir, 'somecode', 'doc.dat'), '#')
172
173 # adding some data in data_files
174 data_dir = join(self.tmp_dir, 'data')
175 os.mkdir(data_dir)
176 self.write_file((data_dir, 'data.dt'), '#')
Tarek Ziadéa30337a2009-02-17 09:47:25 +0000177 some_dir = join(self.tmp_dir, 'some')
178 os.mkdir(some_dir)
Tarek Ziadé14d34a02009-02-17 23:10:18 +0000179 self.write_file((self.tmp_dir, 'inroot.txt'), '#')
Tarek Ziadéa30337a2009-02-17 09:47:25 +0000180 self.write_file((some_dir, 'file.txt'), '#')
181 self.write_file((some_dir, 'other_file.txt'), '#')
182
Tarek Ziadé14d34a02009-02-17 23:10:18 +0000183 dist.data_files = [('data', ['data/data.dt',
184 'inroot.txt',
185 'notexisting']),
Tarek Ziadéa30337a2009-02-17 09:47:25 +0000186 'some/file.txt',
187 'some/other_file.txt']
Tarek Ziadé0d0506e2009-02-16 21:49:12 +0000188
189 # adding a script
190 script_dir = join(self.tmp_dir, 'scripts')
191 os.mkdir(script_dir)
192 self.write_file((script_dir, 'script.py'), '#')
193 dist.scripts = [join('scripts', 'script.py')]
194
Tarek Ziadé0d0506e2009-02-16 21:49:12 +0000195 cmd.formats = ['zip']
196 cmd.use_defaults = True
197
198 cmd.ensure_finalized()
199 cmd.run()
200
201 # now let's check what we have
202 dist_folder = join(self.tmp_dir, 'dist')
203 files = os.listdir(dist_folder)
204 self.assertEquals(files, ['fake-1.0.zip'])
205
206 zip_file = zipfile.ZipFile(join(dist_folder, 'fake-1.0.zip'))
207 try:
208 content = zip_file.namelist()
209 finally:
210 zip_file.close()
211
212 # making sure everything was added
Tarek Ziadé14d34a02009-02-17 23:10:18 +0000213 self.assertEquals(len(content), 11)
Tarek Ziadé0d0506e2009-02-16 21:49:12 +0000214
215 # checking the MANIFEST
Éric Araujobee5cef2010-11-05 23:51:56 +0000216 f = open(join(self.tmp_dir, 'MANIFEST'))
217 try:
218 manifest = f.read()
219 self.assertEquals(manifest, MANIFEST % {'sep': os.sep})
220 finally:
221 f.close()
Tarek Ziadé0d0506e2009-02-16 21:49:12 +0000222
Tarek Ziadé5af55c62009-05-16 16:52:13 +0000223 def test_metadata_check_option(self):
224 # testing the `medata-check` option
225 dist, cmd = self.get_cmd(metadata={})
226
227 # this should raise some warnings !
228 # with the `check` subcommand
229 cmd.ensure_finalized()
230 cmd.run()
231 warnings = self.get_logs(WARN)
232 self.assertEquals(len(warnings), 2)
233
234 # trying with a complete set of metadata
235 self.clear_logs()
236 dist, cmd = self.get_cmd()
237 cmd.ensure_finalized()
238 cmd.metadata_check = 0
239 cmd.run()
240 warnings = self.get_logs(WARN)
241 self.assertEquals(len(warnings), 0)
242
243 def test_check_metadata_deprecated(self):
244 # makes sure make_metadata is deprecated
245 dist, cmd = self.get_cmd()
246 with check_warnings() as w:
247 warnings.simplefilter("always")
248 cmd.check_metadata()
249 self.assertEquals(len(w.warnings), 1)
250
Tarek Ziadéaec039a2009-05-14 12:45:48 +0000251 def test_show_formats(self):
252 with captured_stdout() as stdout:
253 show_formats()
254
255 # the output should be a header line + one line per format
256 num_formats = len(ARCHIVE_FORMATS.keys())
257 output = [line for line in stdout.getvalue().split('\n')
258 if line.strip().startswith('--formats=')]
259 self.assertEquals(len(output), num_formats)
260
Tarek Ziadéda0dc2e2009-05-14 15:21:26 +0000261 def test_finalize_options(self):
262
263 dist, cmd = self.get_cmd()
264 cmd.finalize_options()
265
266 # default options set by finalize
267 self.assertEquals(cmd.manifest, 'MANIFEST')
268 self.assertEquals(cmd.template, 'MANIFEST.in')
269 self.assertEquals(cmd.dist_dir, 'dist')
270
271 # formats has to be a string splitable on (' ', ',') or
272 # a stringlist
273 cmd.formats = 1
274 self.assertRaises(DistutilsOptionError, cmd.finalize_options)
275 cmd.formats = ['zip']
276 cmd.finalize_options()
277
278 # formats has to be known
279 cmd.formats = 'supazipa'
280 self.assertRaises(DistutilsOptionError, cmd.finalize_options)
281
Tarek Ziadé05b30342009-10-02 23:56:02 +0000282
Tarek Ziadéc16a85c2010-05-17 10:38:53 +0000283 def test_get_file_list(self):
284 # make sure MANIFEST is recalculated
285 dist, cmd = self.get_cmd()
286
287 # filling data_files by pointing files in package_data
288 dist.package_data = {'somecode': ['*.txt']}
289 self.write_file((self.tmp_dir, 'somecode', 'doc.txt'), '#')
290 cmd.ensure_finalized()
291 cmd.run()
292
293 f = open(cmd.manifest)
294 try:
295 manifest = [line.strip() for line in f.read().split('\n')
296 if line.strip() != '']
297 finally:
298 f.close()
299
Éric Araujoda668ff2010-08-14 02:30:34 +0000300 self.assertEquals(len(manifest), 5)
Tarek Ziadéc16a85c2010-05-17 10:38:53 +0000301
302 # adding a file
303 self.write_file((self.tmp_dir, 'somecode', 'doc2.txt'), '#')
304
305 # make sure build_py is reinitinialized, like a fresh run
306 build_py = dist.get_command_obj('build_py')
307 build_py.finalized = False
308 build_py.ensure_finalized()
309
310 cmd.run()
311
312 f = open(cmd.manifest)
313 try:
314 manifest2 = [line.strip() for line in f.read().split('\n')
315 if line.strip() != '']
316 finally:
317 f.close()
318
319 # do we have the new file in MANIFEST ?
Éric Araujoda668ff2010-08-14 02:30:34 +0000320 self.assertEquals(len(manifest2), 6)
Tarek Ziadéc16a85c2010-05-17 10:38:53 +0000321 self.assertIn('doc2.txt', manifest2[-1])
322
Éric Araujoda668ff2010-08-14 02:30:34 +0000323 def test_manifest_marker(self):
324 # check that autogenerated MANIFESTs have a marker
325 dist, cmd = self.get_cmd()
326 cmd.ensure_finalized()
327 cmd.run()
328
329 f = open(cmd.manifest)
330 try:
331 manifest = [line.strip() for line in f.read().split('\n')
332 if line.strip() != '']
333 finally:
334 f.close()
335
336 self.assertEqual(manifest[0],
337 '# file GENERATED by distutils, do NOT edit')
338
339 def test_manual_manifest(self):
340 # check that a MANIFEST without a marker is left alone
341 dist, cmd = self.get_cmd()
342 cmd.ensure_finalized()
343 self.write_file((self.tmp_dir, cmd.manifest), 'README.manual')
344 cmd.run()
345
346 f = open(cmd.manifest)
347 try:
348 manifest = [line.strip() for line in f.read().split('\n')
349 if line.strip() != '']
350 finally:
351 f.close()
352
353 self.assertEqual(manifest, ['README.manual'])
Tarek Ziadéc16a85c2010-05-17 10:38:53 +0000354
Benjamin Peterson960cf0f2009-01-09 04:11:44 +0000355def test_suite():
Tarek Ziadé5af55c62009-05-16 16:52:13 +0000356 return unittest.makeSuite(SDistTestCase)
Benjamin Peterson960cf0f2009-01-09 04:11:44 +0000357
358if __name__ == "__main__":
Éric Araujo70ec44a2010-11-06 02:44:43 +0000359 run_unittest(test_suite())