version.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. # Contains the openMSX version number and versioning related functions.
  2. from executils import captureStdout
  3. from makeutils import filterLines
  4. from io import open
  5. from os import makedirs
  6. from os.path import isdir
  7. import re
  8. # Name used for packaging.
  9. packageName = 'openmsx'
  10. # Version number.
  11. packageVersionNumber = '16.0'
  12. # Version code for Android must be an incremental number
  13. # Increase this number for each release build. For a dev build, the
  14. # version number is based on the git commit count but for a release
  15. # build, it must be hardcoded
  16. androidReleaseVersionCode=12
  17. # Note: suffix should be empty or with dash, like "-rc1" or "-test1"
  18. packageVersionSuffix = ''
  19. packageVersion = packageVersionNumber + packageVersionSuffix
  20. # Is this a release version ("True") or development version ("False").
  21. releaseFlag = False
  22. def _extractRevisionFromStdout(log, command, regex):
  23. text = captureStdout(log, command)
  24. if text is None:
  25. # Error logging already done by captureStdout().
  26. return None
  27. # pylint 0.18.0 somehow thinks captureStdout() returns a list, not a string.
  28. lines = text.split('\n') # pylint: disable-msg=E1103
  29. for revision, in filterLines(lines, regex):
  30. print('Revision number found by "%s": %s' % (command, revision), file=log)
  31. return revision
  32. else:
  33. print('Revision number not found in "%s" output:' % command, file=log)
  34. print(str(text), file=log)
  35. return None
  36. def extractGitRevision(log):
  37. return _extractRevisionFromStdout(
  38. log, 'git describe --dirty', r'\S+?-(\S+)$'
  39. )
  40. def extractNumberFromGitRevision(revisionStr):
  41. if revisionStr is None:
  42. return None
  43. if revisionStr == 'dirty':
  44. return None
  45. return re.match(r'(\d+)+', revisionStr).group(0)
  46. _cachedRevision = False # because None is a valid result
  47. def extractRevision():
  48. global _cachedRevision
  49. if _cachedRevision is not False:
  50. return _cachedRevision
  51. if releaseFlag:
  52. # Not necessary, we do not append revision for a release build.
  53. return None
  54. if not isdir('derived'):
  55. makedirs('derived')
  56. with open('derived/version.log', 'w', encoding='utf-8') as log:
  57. print('Extracting revision info...', file=log)
  58. revision = extractGitRevision(log)
  59. print('Revision string: %s' % revision, file=log)
  60. revisionNumber = extractNumberFromGitRevision(revision)
  61. print('Revision number: %s' % revisionNumber, file=log)
  62. _cachedRevision = revision
  63. return revision
  64. def extractRevisionNumber():
  65. return int(extractNumberFromGitRevision(extractRevision()) or 0)
  66. def extractRevisionString():
  67. return extractRevision() or 'unknown'
  68. def getVersionTripleString():
  69. """Version in "x.y.z" format."""
  70. return '%s.%d' % (packageVersionNumber, extractRevisionNumber())
  71. def getDetailedVersion():
  72. if releaseFlag:
  73. return packageVersion
  74. else:
  75. return '%s-%s' % (packageVersion, extractRevisionString())
  76. def getVersionedPackageName():
  77. return '%s-%s' % (packageName, getDetailedVersion())
  78. def countGitCommits():
  79. if not isdir('derived'):
  80. makedirs('derived')
  81. with open('derived/commitCountVersion.log', 'w', encoding='utf-8') as log:
  82. print('Extracting commit count...', file=log)
  83. commitCount = captureStdout(log, 'git rev-list HEAD --count')
  84. print('Commit count: %s' % commitCount, file=log)
  85. return commitCount
  86. def getAndroidVersionCode():
  87. if releaseFlag:
  88. return '%s' % (androidReleaseVersionCode)
  89. else:
  90. return '%s' % ( countGitCommits() )
  91. formatMap = dict(
  92. main=lambda: packageVersionNumber,
  93. plain=lambda: packageVersion,
  94. triple=getVersionTripleString,
  95. detailed=getDetailedVersion,
  96. )
  97. if __name__ == '__main__':
  98. import sys
  99. badFormat = False
  100. for fmt in sys.argv[1:] or ['detailed']:
  101. try:
  102. formatter = formatMap[fmt]
  103. except KeyError:
  104. print('Unknown version format "%s"' % fmt, file=sys.stderr)
  105. badFormat = True
  106. else:
  107. print(formatter())
  108. if badFormat:
  109. print('Supported version formats:', ', '.join(sorted(formatMap.keys())),
  110. file=sys.stderr)
  111. sys.exit(2)