14
14
15
15
import os
16
16
import sys
17
- from os .path import join , exists , isfile , isdir , dirname , basename
18
17
19
18
from pprint import pformat
20
- from distutils .core import Command
19
+ from os .path import join , exists , isfile , isdir , dirname , basename
20
+
21
+
22
+ ### routines to initialize versioning
21
23
22
24
23
25
def find_in_parents (path , name ):
@@ -143,9 +145,11 @@ def setup_versioning():
143
145
144
146
return versionfile
145
147
148
+
146
149
versionfile = setup_versioning ()
147
150
148
- def print_version_info ():
151
+
152
+ def print_version_info (self = None ):
149
153
""" Testable body of a setuptools/distutils command.
150
154
151
155
>>> print_version_info()
@@ -161,21 +165,35 @@ def print_version_info():
161
165
print ('== Version-Info:\n ' + pformat (versionfile .VERSION_INFO ))
162
166
163
167
168
+
169
+ ### versioning config/setup done. start of setuptools helpers
170
+
171
+
172
+ from distutils .core import Command
173
+
174
+ def testable_do_nothing (self = None ):
175
+ """ A helper to increase test coverage.
176
+ To be used on some classes as a method
177
+ where a method override is required, but
178
+ doesn't actually do anything.
179
+
180
+ >>> testable_do_nothing()
181
+ """
182
+
164
183
class cmd_version_info (Command ):
165
184
""" Version info command.
166
185
167
186
Run `./setup.py version` to get detailed info on the latest version.
168
187
"""
169
-
170
188
description = "show versioning configuration and current project version"
171
189
user_options = []
172
190
boolean_options = []
173
191
174
- def initialize_options ( self ): pass
175
- def finalize_options ( self ): pass
176
-
177
- def run ( self ):
178
- print_version_info ()
192
+ # actually methods, but defined outside
193
+ # the class for reuse- and testability.
194
+ initialize_options = testable_do_nothing
195
+ finalize_options = testable_do_nothing
196
+ run = print_version_info
179
197
180
198
181
199
@@ -225,26 +243,26 @@ def render_bumped(**kwd):
225
243
return normalized
226
244
227
245
228
- def do_bump (not_really = None ):
246
+ def do_bump (self = None , test_data = None ):
229
247
""" Execute a version bump (if not testing)
230
248
231
- >>> do_bump(not_really ={'dirt':'','tag_version':{'release':(1,1,2)},'prefix':''})
249
+ >>> do_bump(test_data ={'dirt':'','tag_version':{'release':(1,1,2)},'prefix':''})
232
250
== Next Version: {'release': (1, 1, 3)}
233
251
== Tagging: 1.1.3
234
- >>> do_bump(not_really ={'dirt':'XXX','tag_version':{'release':(1,1,2)},'prefix':''})
252
+ >>> do_bump(test_data ={'dirt':'XXX','tag_version':{'release':(1,1,2)},'prefix':''})
235
253
Traceback (most recent call last):
236
254
...
237
255
SystemExit: 1
238
256
"""
239
- vcs_info = versionfile .VERSION_INFO ['vcs_info' ] if not_really is None else not_really
257
+ vcs_info = versionfile .VERSION_INFO ['vcs_info' ] if test_data is None else test_data
240
258
tag_info = bump_version (vcs_info ['tag_version' ])
241
259
print ('== Next Version: %s' % pformat (tag_info ))
242
260
if vcs_info ['dirt' ]:
243
261
print ("==> Auto bump aborted due to dirty git repository." )
244
262
sys .exit (1 )
245
263
tag = vcs_info ['prefix' ] + render_bumped (** tag_info )
246
264
print ('== Tagging: %s' % tag )
247
- not_really or os .system ('git tag ' + tag )
265
+ test_data or os .system ('git tag ' + tag )
248
266
249
267
class cmd_version_bump (Command ):
250
268
""" Version bump command.
@@ -257,9 +275,9 @@ class cmd_version_bump(Command):
257
275
user_options = []
258
276
boolean_options = []
259
277
260
- def initialize_options ( self ): pass
261
- def finalize_options ( self ): pass
262
- def run ( self ): do_bump ()
278
+ initialize_options = testable_do_nothing
279
+ finalize_options = testable_do_nothing
280
+ run = do_bump
263
281
264
282
265
283
#class cmd_update_versionfile(Command):
@@ -332,20 +350,22 @@ class cmd_build_py(_build_py):
332
350
else :
333
351
from distutils .command .sdist import sdist as _sdist
334
352
335
- def add_to_sdist (base_dir ):
353
+ def add_to_sdist (self = None , base_dir = os . curdir , files = () ):
336
354
""" The custom part of the sdist command.
337
355
338
- >>> add_to_sdist('/tmp')
356
+ >>> add_to_sdist(base_dir= '/tmp')
339
357
== Rendering:
340
358
...
341
- >>> add_to_sdist('/tmp')
359
+ >>> add_to_sdist(base_dir= '/tmp')
342
360
== Rendering:
343
361
...
344
362
"""
345
363
# now locate _version.py in the new base_dir directory
346
364
# (remembering that it may be a hardlink) and replace it with an
347
365
# updated value
348
366
367
+ self and _sdist .make_release_tree (self , base_dir , files )
368
+
349
369
source_versionfile , build_versionfile = read_setup_cfg ()
350
370
target_versionfile = os .path .join (base_dir , build_versionfile )
351
371
static_versionfile = versionfile .render_static_file () if versionfile else 'test_content'
@@ -368,52 +388,60 @@ def add_to_sdist(base_dir):
368
388
except OSError :
369
389
print ("=== Could not add %s to sdist!" % basename (__file__ ))
370
390
391
+ def sdist_run (self = None ):
392
+ """ A mere fake when run as a test... but 199% covered!
371
393
372
- class cmd_sdist (_sdist ):
394
+ >>> sdist_run()
395
+ """
396
+ if self : self .distribution .metadata .version = setup_versioning ().get_version ()
397
+ if self : return _sdist .run (self )
373
398
374
- def run (self ):
375
- self .distribution .metadata .version = setup_versioning ().get_version ()
376
- return _sdist .run (self )
399
+ class cmd_sdist (_sdist ):
377
400
378
- def make_release_tree (self , base_dir , files ):
379
- _sdist .make_release_tree (self , base_dir , files )
380
- add_to_sdist (base_dir )
401
+ run = sdist_run
402
+ make_release_tree = add_to_sdist
381
403
382
404
383
405
from distutils .command .upload import upload as _upload
384
406
407
+ def protected_upload (self = None ):
408
+ """ Allow only uploads with Python 3.
409
+ I experienced problems earlier, when i uploaded packages built
410
+ with python2. They containded .pyc files that made the distribution
411
+ fail on python3 because of a bad magic number error. Since only I use
412
+ this by now, i protect myself from this to happen again by this little
413
+ mechanism. It may be removed or changed in the future.
385
414
386
- class cmd_upload (_upload ):
415
+ >>> protected_upload()
416
+ ==> For backwards compatibility you should only upload packages built with Python 3 to PyPI.
417
+ """
418
+ if self and sys .version_info .major == 3 : return _upload .run (self )
419
+ print ('==> For backwards compatibility you should only upload packages built with Python 3 to PyPI.' )
387
420
421
+ class cmd_upload (_upload ):
388
422
description = "Do the normal upload, but prevent pushing with Python2."
389
-
390
- def run (self ):
391
- if sys .version_info .major == 3 :
392
- return _upload .run (self )
393
- print ('==> For backwards compatibility you should only upload packages built with Python 3 to PyPI.' )
394
- sys .exit (1 )
423
+ run = protected_upload
395
424
396
425
397
- def publish_code (not_really = None ):
426
+ def publish_code (self = None ):
398
427
""" push git and its tags
399
428
400
- >>> publish_code(not_really=True )
429
+ >>> publish_code()
401
430
=== git push
402
431
=== pushing tags also
432
+
433
+ TODO: do not use os.system, there are better ways...
403
434
"""
404
435
print ("=== git push" )
405
- not_really or os .system ('git push' )
436
+ self and os .system ('git push' )
406
437
print ("=== pushing tags also" )
407
- not_really or os .system ('git push --tags' )
438
+ self and os .system ('git push --tags' )
439
+ if self : return cmd_upload .run (self )
408
440
409
441
410
442
class cmd_release (cmd_upload ):
411
-
412
443
description = "Do the protected upload, but push git things first"
413
-
414
- def run (self ):
415
- publish_code ()
416
- return cmd_upload .run (self )
444
+ run = publish_code
417
445
418
446
419
447
0 commit comments