You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

209 lines
6.0 KiB

4 years ago
  1. # Copyright (c) Twisted Matrix Laboratories.
  2. # See LICENSE for details.
  3. from __future__ import absolute_import, division, print_function
  4. import click
  5. import os
  6. import datetime
  7. from incremental import Version
  8. from twisted.python.filepath import FilePath
  9. _VERSIONPY_TEMPLATE = '''"""
  10. Provides %s version information.
  11. """
  12. # This file is auto-generated! Do not edit!
  13. # Use `python -m incremental.update %s` to change this file.
  14. from incremental import Version
  15. __version__ = %s
  16. __all__ = ["__version__"]
  17. '''
  18. _YEAR_START = 2000
  19. def _findPath(path, package):
  20. cwd = FilePath(path)
  21. src_dir = cwd.child("src").child(package.lower())
  22. current_dir = cwd.child(package.lower())
  23. if src_dir.isdir():
  24. return src_dir
  25. elif current_dir.isdir():
  26. return current_dir
  27. else:
  28. raise ValueError(("Can't find under `./src` or `./`. Check the "
  29. "package name is right (note that we expect your "
  30. "package name to be lower cased), or pass it using "
  31. "'--path'."))
  32. def _existing_version(path):
  33. version_info = {}
  34. with path.child("_version.py").open('r') as f:
  35. exec(f.read(), version_info)
  36. return version_info["__version__"]
  37. def _run(package, path, newversion, patch, rc, dev, create,
  38. _date=None, _getcwd=None, _print=print):
  39. if not _getcwd:
  40. _getcwd = os.getcwd
  41. if not _date:
  42. _date = datetime.date.today()
  43. if type(package) != str:
  44. package = package.encode('utf8')
  45. if not path:
  46. path = _findPath(_getcwd(), package)
  47. else:
  48. path = FilePath(path)
  49. if newversion and patch or newversion and dev or newversion and rc:
  50. raise ValueError("Only give --newversion")
  51. if dev and patch or dev and rc:
  52. raise ValueError("Only give --dev")
  53. if create and dev or create and patch or create and rc or \
  54. create and newversion:
  55. raise ValueError("Only give --create")
  56. if newversion:
  57. from pkg_resources import parse_version
  58. existing = _existing_version(path)
  59. st_version = parse_version(newversion)._version
  60. release = list(st_version.release)
  61. if len(release) == 1:
  62. release.append(0)
  63. if len(release) == 2:
  64. release.append(0)
  65. v = Version(
  66. package, *release,
  67. release_candidate=st_version.pre[1] if st_version.pre else None,
  68. dev=st_version.dev[1] if st_version.dev else None)
  69. elif create:
  70. v = Version(package, _date.year - _YEAR_START, _date.month, 0)
  71. existing = v
  72. elif rc and not patch:
  73. existing = _existing_version(path)
  74. if existing.release_candidate:
  75. v = Version(package, existing.major, existing.minor,
  76. existing.micro, existing.release_candidate + 1)
  77. else:
  78. v = Version(package, _date.year - _YEAR_START, _date.month, 0, 1)
  79. elif patch:
  80. if rc:
  81. rc = 1
  82. else:
  83. rc = None
  84. existing = _existing_version(path)
  85. v = Version(package, existing.major, existing.minor,
  86. existing.micro + 1, rc)
  87. elif dev:
  88. existing = _existing_version(path)
  89. if existing.dev is None:
  90. _dev = 0
  91. else:
  92. _dev = existing.dev + 1
  93. v = Version(package, existing.major, existing.minor,
  94. existing.micro, existing.release_candidate, dev=_dev)
  95. else:
  96. existing = _existing_version(path)
  97. if existing.release_candidate:
  98. v = Version(package,
  99. existing.major, existing.minor, existing.micro)
  100. else:
  101. raise ValueError(
  102. "You need to issue a rc before updating the major/minor")
  103. NEXT_repr = repr(Version(package, "NEXT", 0, 0)).split("#")[0]
  104. NEXT_repr_bytes = NEXT_repr.encode('utf8')
  105. version_repr = repr(v).split("#")[0]
  106. version_repr_bytes = version_repr.encode('utf8')
  107. existing_version_repr = repr(existing).split("#")[0]
  108. existing_version_repr_bytes = existing_version_repr.encode('utf8')
  109. _print("Updating codebase to %s" % (v.public()))
  110. for x in path.walk():
  111. if not x.isfile():
  112. continue
  113. original_content = x.getContent()
  114. content = original_content
  115. # Replace previous release_candidate calls to the new one
  116. if existing.release_candidate:
  117. content = content.replace(existing_version_repr_bytes,
  118. version_repr_bytes)
  119. content = content.replace(
  120. (package.encode('utf8') + b" " +
  121. existing.public().encode('utf8')),
  122. (package.encode('utf8') + b" " +
  123. v.public().encode('utf8')))
  124. # Replace NEXT Version calls with the new one
  125. content = content.replace(NEXT_repr_bytes,
  126. version_repr_bytes)
  127. content = content.replace(NEXT_repr_bytes.replace(b"'", b'"'),
  128. version_repr_bytes)
  129. # Replace <package> NEXT with <package> <public>
  130. content = content.replace(package.encode('utf8') + b" NEXT",
  131. (package.encode('utf8') + b" " +
  132. v.public().encode('utf8')))
  133. if content != original_content:
  134. _print("Updating %s" % (x.path,))
  135. with x.open('w') as f:
  136. f.write(content)
  137. _print("Updating %s/_version.py" % (path.path))
  138. with path.child("_version.py").open('w') as f:
  139. f.write(
  140. (_VERSIONPY_TEMPLATE % (
  141. package, package, version_repr)).encode('utf8'))
  142. @click.command()
  143. @click.argument('package')
  144. @click.option('--path', default=None)
  145. @click.option('--newversion', default=None)
  146. @click.option('--patch', is_flag=True)
  147. @click.option('--rc', is_flag=True)
  148. @click.option('--dev', is_flag=True)
  149. @click.option('--create', is_flag=True)
  150. def run(*args, **kwargs):
  151. return _run(*args, **kwargs)
  152. if __name__ == '__main__': # pragma: no cover
  153. run()