list-packageconfig-flags.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #!/usr/bin/env python
  2. # This program is free software; you can redistribute it and/or modify
  3. # it under the terms of the GNU General Public License as published by
  4. # the Free Software Foundation; either version 2 of the License, or
  5. # (at your option) any later version.
  6. #
  7. # This program is distributed in the hope that it will be useful,
  8. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. # GNU General Public License for more details.
  11. #
  12. # You should have received a copy of the GNU General Public License
  13. # along with this program; if not, write to the Free Software Foundation.
  14. #
  15. # Copyright (C) 2013 Wind River Systems, Inc.
  16. #
  17. # - list available pkgs which have PACKAGECONFIG flags
  18. # - list available PACKAGECONFIG flags and all affected pkgs
  19. # - list all pkgs and PACKAGECONFIG information
  20. import sys
  21. import getopt
  22. import os
  23. scripts_path = os.path.abspath(os.path.dirname(os.path.abspath(sys.argv[0])))
  24. lib_path = os.path.abspath(scripts_path + '/../lib')
  25. sys.path = sys.path + [lib_path]
  26. import scriptpath
  27. # For importing the following modules
  28. bitbakepath = scriptpath.add_bitbake_lib_path()
  29. if not bitbakepath:
  30. sys.stderr.write("Unable to find bitbake by searching parent directory of this script or PATH\n")
  31. sys.exit(1)
  32. import bb.cache
  33. import bb.cooker
  34. import bb.providers
  35. import bb.tinfoil
  36. usage_body = ''' list available pkgs which have PACKAGECONFIG flags
  37. OPTION:
  38. -h, --help display this help and exit
  39. -f, --flag list available PACKAGECONFIG flags and all affected pkgs
  40. -a, --all list all pkgs and PACKAGECONFIG information
  41. -p, --prefer list pkgs with preferred version
  42. EXAMPLE:
  43. list-packageconfig-flags.py
  44. list-packageconfig-flags.py -f
  45. list-packageconfig-flags.py -a
  46. list-packageconfig-flags.py -p
  47. list-packageconfig-flags.py -f -p
  48. list-packageconfig-flags.py -a -p
  49. '''
  50. def usage():
  51. print 'Usage: %s [-f|-a] [-p]' % os.path.basename(sys.argv[0])
  52. print usage_body
  53. def get_fnlist(bbhandler, pkg_pn, preferred):
  54. ''' Get all recipe file names '''
  55. if preferred:
  56. (latest_versions, preferred_versions) = bb.providers.findProviders(bbhandler.config_data, bbhandler.cooker.recipecache, pkg_pn)
  57. fn_list = []
  58. for pn in sorted(pkg_pn):
  59. if preferred:
  60. fn_list.append(preferred_versions[pn][1])
  61. else:
  62. fn_list.extend(pkg_pn[pn])
  63. return fn_list
  64. def get_recipesdata(bbhandler, preferred):
  65. ''' Get data of all available recipes which have PACKAGECONFIG flags '''
  66. pkg_pn = bbhandler.cooker.recipecache.pkg_pn
  67. data_dict = {}
  68. for fn in get_fnlist(bbhandler, pkg_pn, preferred):
  69. data = bb.cache.Cache.loadDataFull(fn, bbhandler.cooker.collection.get_file_appends(fn), bbhandler.config_data)
  70. if data.getVarFlags("PACKAGECONFIG"):
  71. data_dict[fn] = data
  72. return data_dict
  73. def collect_pkgs(data_dict):
  74. ''' Collect available pkgs in which have PACKAGECONFIG flags '''
  75. # pkg_dict = {'pkg1': ['flag1', 'flag2',...]}
  76. pkg_dict = {}
  77. for fn in data_dict:
  78. pkgconfigflags = data_dict[fn].getVarFlags("PACKAGECONFIG")
  79. pkgname = data_dict[fn].getVar("P", True)
  80. pkg_dict[pkgname] = sorted(pkgconfigflags.keys())
  81. return pkg_dict
  82. def collect_flags(pkg_dict):
  83. ''' Collect available PACKAGECONFIG flags and all affected pkgs '''
  84. # flag_dict = {'flag': ['pkg1', 'pkg2',...]}
  85. flag_dict = {}
  86. for pkgname, flaglist in pkg_dict.iteritems():
  87. for flag in flaglist:
  88. if flag == "defaultval":
  89. continue
  90. if flag in flag_dict:
  91. flag_dict[flag].append(pkgname)
  92. else:
  93. flag_dict[flag] = [pkgname]
  94. return flag_dict
  95. def display_pkgs(pkg_dict):
  96. ''' Display available pkgs which have PACKAGECONFIG flags '''
  97. pkgname_len = len("PACKAGE NAME") + 1
  98. for pkgname in pkg_dict:
  99. if pkgname_len < len(pkgname):
  100. pkgname_len = len(pkgname)
  101. pkgname_len += 1
  102. header = '%-*s%s' % (pkgname_len, str("PACKAGE NAME"), str("PACKAGECONFIG FLAGS"))
  103. print header
  104. print str("").ljust(len(header), '=')
  105. for pkgname in sorted(pkg_dict):
  106. print('%-*s%s' % (pkgname_len, pkgname, ' '.join(pkg_dict[pkgname])))
  107. def display_flags(flag_dict):
  108. ''' Display available PACKAGECONFIG flags and all affected pkgs '''
  109. flag_len = len("PACKAGECONFIG FLAG") + 5
  110. header = '%-*s%s' % (flag_len, str("PACKAGECONFIG FLAG"), str("PACKAGE NAMES"))
  111. print header
  112. print str("").ljust(len(header), '=')
  113. for flag in sorted(flag_dict):
  114. print('%-*s%s' % (flag_len, flag, ' '.join(sorted(flag_dict[flag]))))
  115. def display_all(data_dict):
  116. ''' Display all pkgs and PACKAGECONFIG information '''
  117. print str("").ljust(50, '=')
  118. for fn in data_dict:
  119. print('%s' % data_dict[fn].getVar("P", True))
  120. print fn
  121. packageconfig = data_dict[fn].getVar("PACKAGECONFIG", True) or ''
  122. if packageconfig.strip() == '':
  123. packageconfig = 'None'
  124. print('PACKAGECONFIG %s' % packageconfig)
  125. for flag,flag_val in data_dict[fn].getVarFlags("PACKAGECONFIG").iteritems():
  126. if flag == "defaultval":
  127. continue
  128. print('PACKAGECONFIG[%s] %s' % (flag, flag_val))
  129. print ''
  130. def main():
  131. listtype = 'pkgs'
  132. preferred = False
  133. pkg_dict = {}
  134. flag_dict = {}
  135. # Collect and validate input
  136. try:
  137. opts, args = getopt.getopt(sys.argv[1:], "hfap", ["help", "flag", "all", "prefer"])
  138. except getopt.GetoptError, err:
  139. print >> sys.stderr,'%s' % str(err)
  140. usage()
  141. sys.exit(2)
  142. for opt, value in opts:
  143. if opt in ('-h', '--help'):
  144. usage()
  145. sys.exit(0)
  146. elif opt in ('-f', '--flag'):
  147. listtype = 'flags'
  148. elif opt in ('-a', '--all'):
  149. listtype = 'all'
  150. elif opt in ('-p', '--prefer'):
  151. preferred = True
  152. else:
  153. assert False, "unhandled option"
  154. bbhandler = bb.tinfoil.Tinfoil()
  155. bbhandler.prepare()
  156. data_dict = get_recipesdata(bbhandler, preferred)
  157. if listtype == 'flags':
  158. pkg_dict = collect_pkgs(data_dict)
  159. flag_dict = collect_flags(pkg_dict)
  160. display_flags(flag_dict)
  161. elif listtype == 'pkgs':
  162. pkg_dict = collect_pkgs(data_dict)
  163. display_pkgs(pkg_dict)
  164. elif listtype == 'all':
  165. display_all(data_dict)
  166. if __name__ == "__main__":
  167. main()