update-documentation-conf 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #!/usr/bin/env python
  2. #
  3. # SPDX-License-Identifier: GPL-2.0-only
  4. #
  5. # documentation.conf update script
  6. #
  7. # Author: Paul Eggleton <paul.eggleton@linux.intel.com>
  8. #
  9. # Copyright (C) 2015 Intel Corporation
  10. #
  11. import sys
  12. import os
  13. import argparse
  14. import re
  15. from lxml import etree
  16. import logging
  17. def logger_create(name):
  18. logger = logging.getLogger(name)
  19. loggerhandler = logging.StreamHandler()
  20. loggerhandler.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))
  21. logger.addHandler(loggerhandler)
  22. logger.setLevel(logging.INFO)
  23. return logger
  24. logger = logger_create('docconfupdater')
  25. def main():
  26. parser = argparse.ArgumentParser(description="documentation.conf updater")
  27. parser.add_argument('basepath', help='Path to OE-Core base directory')
  28. parser.add_argument('-q', '--quiet', help='Print only warnings/errors', action='store_true')
  29. args = parser.parse_args()
  30. if args.quiet:
  31. logger.setLevel(logging.WARN)
  32. if not os.path.isdir(args.basepath):
  33. logger.error('Specified base path %s not found')
  34. return 1
  35. doc_conf = os.path.join(args.basepath, 'meta', 'conf', 'documentation.conf')
  36. if not os.path.exists(doc_conf):
  37. logger.error('Unable to find %s' % doc_conf)
  38. return 1
  39. allowed_flags = ['doc']
  40. flag_re = re.compile(r'\[(.+?)\]')
  41. infos = {}
  42. tree = etree.parse('ref-manual/ref-variables.xml')
  43. root = tree.getroot()
  44. for glossary in root.findall('glossary'):
  45. for glossdiv in glossary.findall('glossdiv'):
  46. for glossentry in glossdiv.findall('glossentry'):
  47. info = glossentry.find('info')
  48. if info is not None:
  49. infoline = ' '.join(info.text.split())
  50. infolinesplit = infoline.split('=', 1)
  51. if len(infoline) < 2:
  52. logger.warn('Invalid info line (no = character), ignoring: %s' % infoline)
  53. continue
  54. flags = flag_re.findall(infolinesplit[0])
  55. if not flags:
  56. logger.warn('Invalid info line (no varflag), ignoring: %s' % infoline)
  57. continue
  58. for flag in flags:
  59. if flag not in allowed_flags:
  60. logger.warn('Invalid info line (varflag %s not in allowed list), ignoring: %s' % (flag, infoline))
  61. continue
  62. infos[infolinesplit[0].rstrip()] = infolinesplit[1].lstrip()
  63. if not infos:
  64. logger.error('ERROR: Unable to find any info tags in the glossary')
  65. return 1
  66. def sortkey(key):
  67. # Underscores sort undesirably, so replace them
  68. return key.split('[')[0].replace('_', '-')
  69. changed = False
  70. lines = []
  71. invars = False
  72. lastletter = None
  73. added = []
  74. with open(doc_conf, 'r') as dcf:
  75. for line in dcf:
  76. if not invars:
  77. if line.startswith('#') and 'DESCRIPTIONS FOR VARIABLES' in line:
  78. invars = True
  79. elif not line.startswith('#'):
  80. linesplit = line.split('=', 1)
  81. if len(linesplit) > 1:
  82. key = linesplit[0].rstrip()
  83. lastletter = key[0]
  84. # Find anything in the dict that should come before the current key
  85. for dkey in sorted(infos.keys()):
  86. if sortkey(dkey) < sortkey(key):
  87. lines.append('%s = %s\n' % (dkey, infos[dkey]))
  88. added.append(dkey)
  89. del infos[dkey]
  90. changed = True
  91. newvalue = infos.get(key, None)
  92. if newvalue:
  93. del infos[key]
  94. if newvalue != linesplit[1].strip():
  95. lines.append('%s = %s\n' % (key, newvalue))
  96. changed = True
  97. continue
  98. elif key in added:
  99. # We already added a new value for this key, so skip it
  100. continue
  101. elif lastletter:
  102. # Ensure we write out anything anything left over for this letter
  103. for dkey in sorted(infos.keys()):
  104. if dkey[0] == lastletter:
  105. lines.append('%s = %s\n' % (dkey, infos[dkey]))
  106. del infos[dkey]
  107. changed = True
  108. elif dkey[0] > lastletter:
  109. # List is sorted, so we're done
  110. break
  111. lastletter = None
  112. lines.append(line)
  113. if not invars:
  114. logger.error('ERROR: Unable to find variables section in documentation.conf')
  115. return 1
  116. if infos:
  117. changed = True
  118. # Write out anything left over
  119. lines.append('\n\n')
  120. for key in sorted(infos.keys()):
  121. lines.append('%s = %s\n' % (key, infos[key]))
  122. if changed:
  123. logger.info('Updating %s' % doc_conf)
  124. with open(doc_conf, 'w') as dcf:
  125. for line in lines:
  126. dcf.write(line)
  127. else:
  128. logger.info('No changes required')
  129. return 0
  130. if __name__ == "__main__":
  131. try:
  132. ret = main()
  133. except Exception:
  134. ret = 1
  135. import traceback
  136. traceback.print_exc(5)
  137. sys.exit(ret)