devtools.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #!/usr/bin/env python
  2. import os
  3. import sys
  4. import re
  5. import tempfile
  6. from cement.core.foundation import CementApp
  7. from cement.core.controller import CementBaseController, expose
  8. from cement.utils.version import get_version
  9. from cement.utils import shell
  10. VERSION = get_version()
  11. class CementDevtoolsController(CementBaseController):
  12. class Meta:
  13. label = 'base'
  14. arguments = [
  15. (['-y, --noprompt'],
  16. dict(help='answer yes to prompts.', action='store_true',
  17. dest='noprompt')),
  18. (['--ignore-errors'],
  19. dict(help="don't stop operations because of errors",
  20. action='store_true', dest='ignore_errors')),
  21. (['--loud'], dict(help='add more verbose output',
  22. action='store_true', dest='loud')),
  23. (['modifier1'],
  24. dict(help='command modifier positional argument', nargs='?')),
  25. ]
  26. def _do_error(self, msg):
  27. if self.app.pargs.ignore_errors:
  28. self.app.log.error(msg)
  29. else:
  30. raise Exception(msg)
  31. @expose(hide=True)
  32. def default(self):
  33. raise AssertionError("A sub-command is required. See --help.")
  34. def _do_git(self):
  35. # make sure we don't have any uncommitted changes
  36. print('Checking for Uncommitted Changes')
  37. out, err, res = shell.exec_cmd(['git', '--no-pager', 'diff'])
  38. if len(out) > 0:
  39. self._do_error('There are uncommitted changes. See `git status`.')
  40. # make sure we don't have any un-added files
  41. print('Checking for Untracked Files')
  42. out, err, res = shell.exec_cmd(['git', 'status'])
  43. if re.match('Untracked files', out):
  44. self._do_error('There are untracked files. See `git status`.')
  45. # make sure there isn't an existing tag
  46. print("Checking for Duplicate Git Tag")
  47. out, err, res = shell.exec_cmd(['git', 'tag'])
  48. for ver in out.split('\n'):
  49. if ver == VERSION:
  50. self._do_error("Tag %s already exists" % VERSION)
  51. print("Tagging Git Release")
  52. out, err, res = shell.exec_cmd(['git', 'tag', '-a', '-m', VERSION,
  53. VERSION])
  54. if res > 0:
  55. self._do_error("Unable to tag release with git.")
  56. def _do_tests(self):
  57. print('Running Nose Tests')
  58. out, err, res = shell.exec_cmd(['which', 'nosetests'])
  59. if self.app.pargs.loud:
  60. cmd_args = ['coverage', 'run', out.strip(), '--verbosity=3']
  61. res = shell.exec_cmd2(cmd_args)
  62. else:
  63. cmd_args = ['coverage', 'run', out.strip(), '--verbosity=0']
  64. out, err, res = shell.exec_cmd(cmd_args)
  65. if res > 0:
  66. self._do_error("\n\nNose tests did not pass.\n\n" +
  67. "$ %s\n%s" % (' '.join(cmd_args), err))
  68. def _do_pep8(self):
  69. print("Checking PEP8 Compliance")
  70. cmd_args = ['pep8', '-r', 'cement/', '--exclude=*.pyc']
  71. out, err, res = shell.exec_cmd(cmd_args)
  72. if res > 0:
  73. self._do_error("\n\nPEP8 checks did not pass.\n\n" +
  74. "$ %s\n%s" % (' '.join(cmd_args), out))
  75. @expose(help='run all unit tests')
  76. def run_tests(self):
  77. print('')
  78. print('Python Version: %s' % sys.version)
  79. print('')
  80. print("Running Tests for Cement Version %s" % VERSION)
  81. print('-' * 77)
  82. self._do_pep8()
  83. self._do_tests()
  84. print('')
  85. def _do_sphinx(self, dest_path):
  86. print("Building Documentation")
  87. cmd_args = ['rm', '-rf', 'docs/build/*']
  88. cmd_args = ['sphinx-build', 'doc/source', dest_path]
  89. out, err, res = shell.exec_cmd(cmd_args)
  90. if res > 0:
  91. self._do_error("\n\nFailed to build sphinx documentation\n\n" +
  92. "$ %s\n%s" % (' '.join(cmd_args), out))
  93. @expose(help='create a cement release')
  94. def make_release(self):
  95. print('')
  96. print("Making Release for Version %s" % VERSION)
  97. print('-' * 77)
  98. if not self.app.pargs.noprompt:
  99. res = raw_input("Continue? [yN] ")
  100. if res not in ['Y', 'y', '1']:
  101. sys.exit(1)
  102. tmp = tempfile.mkdtemp()
  103. print("Destination: %s" % tmp)
  104. os.makedirs(os.path.join(tmp, 'source'))
  105. os.makedirs(os.path.join(tmp, 'doc'))
  106. self._do_pep8()
  107. self._do_tests()
  108. self._do_git()
  109. self._do_sphinx(os.path.join(tmp, 'doc'))
  110. tar_path = os.path.join(tmp, 'source', 'cement-%s.tar' % VERSION)
  111. gzip_path = "%s.gz" % tar_path
  112. print("Generating Release Files")
  113. cmd_args = ['git', 'archive', VERSION,
  114. '--prefix=cement-%s/' % VERSION,
  115. '--output=%s' % tar_path]
  116. out, err, res = shell.exec_cmd(cmd_args)
  117. cmd_args = ['gzip', tar_path]
  118. out, err, res = shell.exec_cmd(cmd_args)
  119. if res > 0:
  120. self._do_error("\n\nFailed generating git archive.\n\n" +
  121. "$ %s" % (' '.join(cmd_args), err))
  122. print('')
  123. @expose(help='get the current version of the sources')
  124. def get_version(self):
  125. print(VERSION)
  126. class CementDevtoolsApp(CementApp):
  127. class Meta:
  128. label = 'cement-devtools'
  129. base_controller = CementDevtoolsController
  130. def main():
  131. app = CementDevtoolsApp('cement-devtools')
  132. try:
  133. app.setup()
  134. app.run()
  135. except AssertionError as e:
  136. print("AssertionError => %s" % e.args[0])
  137. finally:
  138. app.close()
  139. if __name__ == '__main__':
  140. main()