yocto-vars.py 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #!/usr/bin/env python
  2. from hashlib import md5
  3. from pathlib import Path
  4. import re
  5. import sys
  6. import sphinx
  7. from sphinx.application import Sphinx
  8. # This extension uses pyyaml, report an explicit
  9. # error message if it's not installed
  10. try:
  11. import yaml
  12. except ImportError:
  13. sys.stderr.write("The Yocto Project Sphinx documentation requires PyYAML.\
  14. \nPlease make sure to install pyyaml Python package.\n")
  15. sys.exit(1)
  16. __version__ = '1.0'
  17. # Variables substitutions. Uses {VAR} subst using variables defined in poky.yaml
  18. # Each .rst file is processed after source-read event (subst_vars_replace runs once per file)
  19. subst_vars = {}
  20. poky_hash = ""
  21. def subst_vars_replace(app: Sphinx, docname, source):
  22. result = source[0]
  23. for k in subst_vars:
  24. result = result.replace("&"+k+";", subst_vars[k])
  25. source[0] = result
  26. def yocto_vars_env_get_outdated(app: Sphinx, env, added, changed, removed):
  27. '''
  28. If poky.yaml changed (BUILDDIR/.poky.yaml.cache does not exist or contains
  29. an md5sum different from poky.yaml's current md5sum), force rebuild of all
  30. *.rst files in SOURCEDIR whose content has at least one occurence of `&.*;`
  31. (see PATTERN global variable).
  32. '''
  33. try:
  34. poky_cache = Path(app.outdir) / ".poky.yaml.cache"
  35. cache_hash = poky_cache.read_text()
  36. except FileNotFoundError:
  37. cache_hash = None
  38. if poky_hash == cache_hash:
  39. return []
  40. docs = []
  41. for p in Path(app.srcdir).rglob("*.rst"):
  42. if PATTERN.search(p.read_text()):
  43. p_rel_no_ext = p.relative_to(app.srcdir).parent / p.stem
  44. docs.append(str(p_rel_no_ext))
  45. return docs
  46. def yocto_vars_build_finished(app: Sphinx, exception):
  47. poky_cache = Path(app.outdir) / ".poky.yaml.cache"
  48. poky_cache.write_text(poky_hash)
  49. return []
  50. PATTERN = re.compile(r'&(.*?);')
  51. def expand(val, src):
  52. return PATTERN.sub(lambda m: expand(src.get(m.group(1), ''), src), val)
  53. def setup(app: Sphinx):
  54. global poky_hash
  55. with open("poky.yaml") as file:
  56. hasher = md5()
  57. buff = file.read()
  58. hasher.update(buff.encode('utf-8'))
  59. poky_hash = hasher.hexdigest()
  60. subst_vars.update(yaml.safe_load(buff))
  61. for k in subst_vars:
  62. subst_vars[k] = expand(subst_vars[k], subst_vars)
  63. app.connect('source-read', subst_vars_replace)
  64. app.connect('env-get-outdated', yocto_vars_env_get_outdated)
  65. app.connect('build-finished', yocto_vars_build_finished)
  66. return dict(
  67. version = __version__,
  68. parallel_read_safe = True,
  69. parallel_write_safe = True
  70. )