list-packageconfig-flags.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #!/usr/bin/env python3
  2. # Copyright (C) 2013 Wind River Systems, Inc.
  3. # Copyright (C) 2014 Intel Corporation
  4. #
  5. # SPDX-License-Identifier: GPL-2.0-or-later
  6. #
  7. # - list available recipes which have PACKAGECONFIG flags
  8. # - list available PACKAGECONFIG flags and all affected recipes
  9. # - list all recipes and PACKAGECONFIG information
  10. import sys
  11. import optparse
  12. import os
  13. scripts_path = os.path.abspath(os.path.dirname(os.path.abspath(sys.argv[0])))
  14. lib_path = os.path.abspath(scripts_path + '/../lib')
  15. sys.path = sys.path + [lib_path]
  16. import scriptpath
  17. # For importing the following modules
  18. bitbakepath = scriptpath.add_bitbake_lib_path()
  19. if not bitbakepath:
  20. sys.stderr.write("Unable to find bitbake by searching parent directory of this script or PATH\n")
  21. sys.exit(1)
  22. import bb.cooker
  23. import bb.providers
  24. import bb.tinfoil
  25. def get_fnlist(bbhandler, pkg_pn, preferred):
  26. ''' Get all recipe file names '''
  27. if preferred:
  28. (latest_versions, preferred_versions) = bb.providers.findProviders(bbhandler.config_data, bbhandler.cooker.recipecaches[''], pkg_pn)
  29. fn_list = []
  30. for pn in sorted(pkg_pn):
  31. if preferred:
  32. fn_list.append(preferred_versions[pn][1])
  33. else:
  34. fn_list.extend(pkg_pn[pn])
  35. return fn_list
  36. def get_recipesdata(bbhandler, preferred):
  37. ''' Get data of all available recipes which have PACKAGECONFIG flags '''
  38. pkg_pn = bbhandler.cooker.recipecaches[''].pkg_pn
  39. data_dict = {}
  40. for fn in get_fnlist(bbhandler, pkg_pn, preferred):
  41. data = bbhandler.parse_recipe_file(fn)
  42. flags = data.getVarFlags("PACKAGECONFIG")
  43. flags.pop('doc', None)
  44. if flags:
  45. data_dict[fn] = data
  46. return data_dict
  47. def collect_pkgs(data_dict):
  48. ''' Collect available pkgs in which have PACKAGECONFIG flags '''
  49. # pkg_dict = {'pkg1': ['flag1', 'flag2',...]}
  50. pkg_dict = {}
  51. for fn in data_dict:
  52. pkgconfigflags = data_dict[fn].getVarFlags("PACKAGECONFIG")
  53. pkgconfigflags.pop('doc', None)
  54. pkgname = data_dict[fn].getVar("PN")
  55. pkg_dict[pkgname] = sorted(pkgconfigflags.keys())
  56. return pkg_dict
  57. def collect_flags(pkg_dict):
  58. ''' Collect available PACKAGECONFIG flags and all affected pkgs '''
  59. # flag_dict = {'flag': ['pkg1', 'pkg2',...]}
  60. flag_dict = {}
  61. for pkgname, flaglist in pkg_dict.items():
  62. for flag in flaglist:
  63. if flag in flag_dict:
  64. flag_dict[flag].append(pkgname)
  65. else:
  66. flag_dict[flag] = [pkgname]
  67. return flag_dict
  68. def display_pkgs(pkg_dict):
  69. ''' Display available pkgs which have PACKAGECONFIG flags '''
  70. pkgname_len = len("RECIPE NAME") + 1
  71. for pkgname in pkg_dict:
  72. if pkgname_len < len(pkgname):
  73. pkgname_len = len(pkgname)
  74. pkgname_len += 1
  75. header = '%-*s%s' % (pkgname_len, str("RECIPE NAME"), str("PACKAGECONFIG FLAGS"))
  76. print(header)
  77. print(str("").ljust(len(header), '='))
  78. for pkgname in sorted(pkg_dict):
  79. print('%-*s%s' % (pkgname_len, pkgname, ' '.join(pkg_dict[pkgname])))
  80. def display_flags(flag_dict):
  81. ''' Display available PACKAGECONFIG flags and all affected pkgs '''
  82. flag_len = len("PACKAGECONFIG FLAG") + 5
  83. header = '%-*s%s' % (flag_len, str("PACKAGECONFIG FLAG"), str("RECIPE NAMES"))
  84. print(header)
  85. print(str("").ljust(len(header), '='))
  86. for flag in sorted(flag_dict):
  87. print('%-*s%s' % (flag_len, flag, ' '.join(sorted(flag_dict[flag]))))
  88. def display_all(data_dict):
  89. ''' Display all pkgs and PACKAGECONFIG information '''
  90. print(str("").ljust(50, '='))
  91. for fn in data_dict:
  92. print('%s' % data_dict[fn].getVar("P"))
  93. print(fn)
  94. packageconfig = data_dict[fn].getVar("PACKAGECONFIG") or ''
  95. if packageconfig.strip() == '':
  96. packageconfig = 'None'
  97. print('PACKAGECONFIG %s' % packageconfig)
  98. for flag,flag_val in data_dict[fn].getVarFlags("PACKAGECONFIG").items():
  99. if flag == "doc":
  100. continue
  101. print('PACKAGECONFIG[%s] %s' % (flag, flag_val))
  102. print('')
  103. def main():
  104. pkg_dict = {}
  105. flag_dict = {}
  106. # Collect and validate input
  107. parser = optparse.OptionParser(
  108. description = "Lists recipes and PACKAGECONFIG flags. Without -a or -f, recipes and their available PACKAGECONFIG flags are listed.",
  109. usage = """
  110. %prog [options]""")
  111. parser.add_option("-f", "--flags",
  112. help = "list available PACKAGECONFIG flags and affected recipes",
  113. action="store_const", dest="listtype", const="flags", default="recipes")
  114. parser.add_option("-a", "--all",
  115. help = "list all recipes and PACKAGECONFIG information",
  116. action="store_const", dest="listtype", const="all")
  117. parser.add_option("-p", "--preferred-only",
  118. help = "where multiple recipe versions are available, list only the preferred version",
  119. action="store_true", dest="preferred", default=False)
  120. options, args = parser.parse_args(sys.argv)
  121. with bb.tinfoil.Tinfoil() as bbhandler:
  122. bbhandler.prepare()
  123. print("Gathering recipe data...")
  124. data_dict = get_recipesdata(bbhandler, options.preferred)
  125. if options.listtype == 'flags':
  126. pkg_dict = collect_pkgs(data_dict)
  127. flag_dict = collect_flags(pkg_dict)
  128. display_flags(flag_dict)
  129. elif options.listtype == 'recipes':
  130. pkg_dict = collect_pkgs(data_dict)
  131. display_pkgs(pkg_dict)
  132. elif options.listtype == 'all':
  133. display_all(data_dict)
  134. if __name__ == "__main__":
  135. main()